diff options
Diffstat (limited to 'lib/zlib_inflate/inflate.c')
-rw-r--r-- | lib/zlib_inflate/inflate.c | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c index 7e1e3114a73e..0ad1ebf00947 100644 --- a/lib/zlib_inflate/inflate.c +++ b/lib/zlib_inflate/inflate.c | |||
@@ -332,14 +332,14 @@ static int zlib_inflateSyncPacket(z_streamp strm) | |||
332 | int zlib_inflate(z_streamp strm, int flush) | 332 | int zlib_inflate(z_streamp strm, int flush) |
333 | { | 333 | { |
334 | struct inflate_state *state; | 334 | struct inflate_state *state; |
335 | unsigned char *next; /* next input */ | 335 | const unsigned char *next; /* next input */ |
336 | unsigned char *put; /* next output */ | 336 | unsigned char *put; /* next output */ |
337 | unsigned have, left; /* available input and output */ | 337 | unsigned have, left; /* available input and output */ |
338 | unsigned long hold; /* bit buffer */ | 338 | unsigned long hold; /* bit buffer */ |
339 | unsigned bits; /* bits in bit buffer */ | 339 | unsigned bits; /* bits in bit buffer */ |
340 | unsigned in, out; /* save starting available input and output */ | 340 | unsigned in, out; /* save starting available input and output */ |
341 | unsigned copy; /* number of stored or match bytes to copy */ | 341 | unsigned copy; /* number of stored or match bytes to copy */ |
342 | unsigned char *from; /* where to copy match bytes from */ | 342 | unsigned char *from; /* where to copy match bytes from */ |
343 | code this; /* current decoding table entry */ | 343 | code this; /* current decoding table entry */ |
344 | code last; /* parent table entry */ | 344 | code last; /* parent table entry */ |
345 | unsigned len; /* length to copy for repeats, bits to drop */ | 345 | unsigned len; /* length to copy for repeats, bits to drop */ |
@@ -897,7 +897,7 @@ int zlib_inflateIncomp(z_stream *z) | |||
897 | 897 | ||
898 | /* Setup some variables to allow misuse of updateWindow */ | 898 | /* Setup some variables to allow misuse of updateWindow */ |
899 | z->avail_out = 0; | 899 | z->avail_out = 0; |
900 | z->next_out = z->next_in + z->avail_in; | 900 | z->next_out = (unsigned char*)z->next_in + z->avail_in; |
901 | 901 | ||
902 | zlib_updatewindow(z, z->avail_in); | 902 | zlib_updatewindow(z, z->avail_in); |
903 | 903 | ||
@@ -916,3 +916,50 @@ int zlib_inflateIncomp(z_stream *z) | |||
916 | 916 | ||
917 | return Z_OK; | 917 | return Z_OK; |
918 | } | 918 | } |
919 | |||
920 | #include <linux/errno.h> | ||
921 | #include <linux/slab.h> | ||
922 | #include <linux/vmalloc.h> | ||
923 | |||
924 | /* Utility function: initialize zlib, unpack binary blob, clean up zlib, | ||
925 | * return len or negative error code. */ | ||
926 | int zlib_inflate_blob(void *gunzip_buf, unsigned sz, const void *buf, unsigned len) | ||
927 | { | ||
928 | const u8 *zbuf = buf; | ||
929 | struct z_stream_s *strm; | ||
930 | int rc; | ||
931 | |||
932 | rc = -ENOMEM; | ||
933 | strm = kmalloc(sizeof(*strm), GFP_KERNEL); | ||
934 | if (strm == NULL) | ||
935 | goto gunzip_nomem1; | ||
936 | strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); | ||
937 | if (strm->workspace == NULL) | ||
938 | goto gunzip_nomem2; | ||
939 | |||
940 | /* gzip header (1f,8b,08... 10 bytes total + possible asciz filename) | ||
941 | * expected to be stripped from input */ | ||
942 | |||
943 | strm->next_in = zbuf; | ||
944 | strm->avail_in = len; | ||
945 | strm->next_out = gunzip_buf; | ||
946 | strm->avail_out = sz; | ||
947 | |||
948 | rc = zlib_inflateInit2(strm, -MAX_WBITS); | ||
949 | if (rc == Z_OK) { | ||
950 | rc = zlib_inflate(strm, Z_FINISH); | ||
951 | /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */ | ||
952 | if (rc == Z_STREAM_END) | ||
953 | rc = sz - strm->avail_out; | ||
954 | else | ||
955 | rc = -EINVAL; | ||
956 | zlib_inflateEnd(strm); | ||
957 | } else | ||
958 | rc = -EINVAL; | ||
959 | |||
960 | kfree(strm->workspace); | ||
961 | gunzip_nomem2: | ||
962 | kfree(strm); | ||
963 | gunzip_nomem1: | ||
964 | return rc; /* returns Z_OK (0) if successful */ | ||
965 | } | ||