... | ... |
@@ -125,7 +125,9 @@ static int scanzws(cli_ctx *ctx, struct swf_file_hdr *hdr) |
125 | 125 |
struct CLI_LZMA lz; |
126 | 126 |
unsigned char inbuff[FILEBUFF], outbuff[FILEBUFF]; |
127 | 127 |
fmap_t *map = *ctx->fmap; |
128 |
+ /* strip off header */ |
|
128 | 129 |
off_t offset = 8; |
130 |
+ uint32_t d_insize; |
|
129 | 131 |
size_t outsize = 8; |
130 | 132 |
int ret, lret, count; |
131 | 133 |
char *tmpname; |
... | ... |
@@ -148,11 +150,52 @@ static int scanzws(cli_ctx *ctx, struct swf_file_hdr *hdr) |
148 | 148 |
return CL_EWRITE; |
149 | 149 |
} |
150 | 150 |
|
151 |
- lz.avail_in = 0; |
|
151 |
+ /* read 4 bytes (for compressed 32-bit filesize) [not used for LZMA] */ |
|
152 |
+ if (fmap_readn(map, &d_insize, offset, sizeof(d_insize)) != sizeof(d_insize)) { |
|
153 |
+ cli_errmsg("scanzws: Error reading SWF file\n"); |
|
154 |
+ close(fd); |
|
155 |
+ if (cli_unlink(tmpname)) { |
|
156 |
+ free(tmpname); |
|
157 |
+ return CL_EUNLINK; |
|
158 |
+ } |
|
159 |
+ free(tmpname); |
|
160 |
+ return CL_EREAD; |
|
161 |
+ } |
|
162 |
+ offset += sizeof(d_insize); |
|
163 |
+ |
|
164 |
+ /* check if declared input size matches actual output size */ |
|
165 |
+ /* map->len = header (8 bytes) + d_insize (4 bytes) + flags (5 bytes) + compressed stream */ |
|
166 |
+ if (d_insize != (map->len - 17)) { |
|
167 |
+ cli_warnmsg("SWF: declared input length != compressed stream size, %u != %llu\n", |
|
168 |
+ d_insize, (long long unsigned)(map->len - 17)); |
|
169 |
+ } else { |
|
170 |
+ cli_dbgmsg("SWF: declared input length == compressed stream size, %u == %llu\n", |
|
171 |
+ d_insize, (long long unsigned)(map->len - 17)); |
|
172 |
+ } |
|
173 |
+ |
|
174 |
+ /* first buffer required for initializing LZMA */ |
|
175 |
+ ret = fmap_readn(map, inbuff, offset, FILEBUFF); |
|
176 |
+ if (ret < 0) { |
|
177 |
+ cli_errmsg("scanzws: Error reading SWF file\n"); |
|
178 |
+ close(fd); |
|
179 |
+ if (cli_unlink(tmpname)) { |
|
180 |
+ free(tmpname); |
|
181 |
+ return CL_EUNLINK; |
|
182 |
+ } |
|
183 |
+ free(tmpname); |
|
184 |
+ return CL_EUNPACK; |
|
185 |
+ } |
|
186 |
+ if (!ret) |
|
187 |
+ return CL_EFORMAT; /* likely truncated */ |
|
188 |
+ offset += ret; |
|
189 |
+ |
|
190 |
+ memset(&lz, 0, sizeof(lz)); |
|
152 | 191 |
lz.next_in = inbuff; |
153 | 192 |
lz.next_out = outbuff; |
193 |
+ lz.avail_in = ret; |
|
194 |
+ lz.avail_out = FILEBUFF; |
|
154 | 195 |
|
155 |
- lret = cli_LzmaInit(&lz, 0); |
|
196 |
+ lret = cli_LzmaInit(&lz, hdr->filesize); |
|
156 | 197 |
if (lret != LZMA_RESULT_OK) { |
157 | 198 |
cli_errmsg("scanzws: LzmaInit() failed\n"); |
158 | 199 |
close(fd); |
... | ... |
@@ -164,9 +207,10 @@ static int scanzws(cli_ctx *ctx, struct swf_file_hdr *hdr) |
164 | 164 |
return CL_EUNPACK; |
165 | 165 |
} |
166 | 166 |
|
167 |
- do { |
|
167 |
+ while (lret == LZMA_RESULT_OK) { |
|
168 | 168 |
if (lz.avail_in == 0) { |
169 | 169 |
lz.next_in = inbuff; |
170 |
+ |
|
170 | 171 |
ret = fmap_readn(map, inbuff, offset, FILEBUFF); |
171 | 172 |
if (ret < 0) { |
172 | 173 |
cli_errmsg("scanzws: Error reading SWF file\n"); |
... | ... |
@@ -204,11 +248,11 @@ static int scanzws(cli_ctx *ctx, struct swf_file_hdr *hdr) |
204 | 204 |
} |
205 | 205 |
lz.next_out = outbuff; |
206 | 206 |
lz.avail_out = FILEBUFF; |
207 |
- } while(lret == LZMA_RESULT_OK); |
|
207 |
+ } |
|
208 | 208 |
|
209 | 209 |
cli_LzmaShutdown(&lz); |
210 | 210 |
|
211 |
- if (lret != LZMA_STREAM_END || lret != LZMA_RESULT_OK) { |
|
211 |
+ if (lret != LZMA_STREAM_END && lret != LZMA_RESULT_OK) { |
|
212 | 212 |
/* outsize starts at 8, therefore, if its still 8, nothing was decompressed */ |
213 | 213 |
if (outsize == 8) { |
214 | 214 |
cli_infomsg(ctx, "scanzws: Error decompressing SWF file. No data decompressed.\n"); |
... | ... |
@@ -222,9 +266,17 @@ static int scanzws(cli_ctx *ctx, struct swf_file_hdr *hdr) |
222 | 222 |
} |
223 | 223 |
cli_infomsg(ctx, "scanzws: Error decompressing SWF file. Scanning what was decompressed.\n"); |
224 | 224 |
} |
225 |
- |
|
226 | 225 |
cli_dbgmsg("SWF: Decompressed[LZMA] to %s, size %d\n", tmpname, outsize); |
227 | 226 |
|
227 |
+ /* check if declared output size matches actual output size */ |
|
228 |
+ if (hdr->filesize != outsize) { |
|
229 |
+ cli_warnmsg("SWF: declared output length != inflated stream size, %u != %llu\n", |
|
230 |
+ hdr->filesize, (long long unsigned)outsize); |
|
231 |
+ } else { |
|
232 |
+ cli_dbgmsg("SWF: declared output length == inflated stream size, %u == %llu\n", |
|
233 |
+ hdr->filesize, (long long unsigned)outsize); |
|
234 |
+ } |
|
235 |
+ |
|
228 | 236 |
ret = cli_magic_scandesc(fd, ctx); |
229 | 237 |
|
230 | 238 |
close(fd); |
... | ... |
@@ -347,6 +399,15 @@ static int scancws(cli_ctx *ctx, struct swf_file_hdr *hdr) |
347 | 347 |
} |
348 | 348 |
cli_dbgmsg("SWF: Decompressed[zlib] to %s, size %d\n", tmpname, outsize); |
349 | 349 |
|
350 |
+ /* check if declared output size matches actual output size */ |
|
351 |
+ if (hdr->filesize != outsize) { |
|
352 |
+ cli_warnmsg("SWF: declared output length != inflated stream size, %u != %llu\n", |
|
353 |
+ hdr->filesize, (long long unsigned)outsize); |
|
354 |
+ } else { |
|
355 |
+ cli_dbgmsg("SWF: declared output length == inflated stream size, %u == %llu\n", |
|
356 |
+ hdr->filesize, (long long unsigned)outsize); |
|
357 |
+ } |
|
358 |
+ |
|
350 | 359 |
ret = cli_magic_scandesc(fd, ctx); |
351 | 360 |
|
352 | 361 |
close(fd); |