summaryrefslogtreecommitdiff
path: root/lib/zlib
diff options
context:
space:
mode:
authorAnatolij Gustschin <agust@denx.de>2011-10-15 06:32:52 +0000
committerWolfgang Denk <wd@denx.de>2011-10-17 21:45:35 +0200
commit92faa8b109180fa28ec899479f676e62a3a391b7 (patch)
treeef90ff3d09f24344412d544ac273f1b646cf17aa /lib/zlib
parent8d80d057537fd536c8cc2252dc18ec3dea9a47e2 (diff)
downloadu-boot-92faa8b109180fa28ec899479f676e62a3a391b7.tar.gz
zlib: handle overflow while calculating available stream input size
If compressed data is located in sectors at the end of the flash and it's offset + input stream size > 0xFFFFFFFF, the uncompressing time is very long, since processing of the stream is done bytewise (and not blockwise) due to overflow in inflate_fast() while calculation and checking for enough input available. Check for this overflow condition and limit the available stream input size to the actually max. possible input size. This fixes the problem. The issue is easily reproduceable by placing a gziped bitmap in flash, e.g. at FFF80000, and running 'bmp' commands like 'bmp info FFF80000' or 'bmp display FFF80000'. The uncompressing can take up to 3 sec. whereas it should normaly take a fraction of a second. If the 'splashimage' environment variable points to this address, the booting time also increases significantly. Signed-off-by: Anatolij Gustschin <agust@denx.de>
Diffstat (limited to 'lib/zlib')
-rw-r--r--lib/zlib/inffast.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/lib/zlib/inffast.c b/lib/zlib/inffast.c
index 8e823df4cf..4834b0c86e 100644
--- a/lib/zlib/inffast.c
+++ b/lib/zlib/inffast.c
@@ -100,6 +100,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
state = (struct inflate_state FAR *)strm->state;
in = strm->next_in - OFF;
last = in + (strm->avail_in - 5);
+ if (in > last && strm->avail_in > 5) {
+ /*
+ * overflow detected, limit strm->avail_in to the
+ * max. possible size and recalculate last
+ */
+ strm->avail_in = 0xffffffff - (unsigned int)in;
+ last = in + (strm->avail_in - 5);
+ }
out = strm->next_out - OFF;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);