... | ... |
@@ -47,6 +47,11 @@ |
47 | 47 |
|
48 | 48 |
#define HWP5_DEBUG 0 |
49 | 49 |
#define HWP3_DEBUG 1 |
50 |
+#if HWP5_DEBUG |
|
51 |
+#define hwp5_debug(...) cli_dbgmsg(__VA_ARGS__) |
|
52 |
+#else |
|
53 |
+#define hwp5_debug(...) ; |
|
54 |
+#endif |
|
50 | 55 |
#if HWP3_DEBUG |
51 | 56 |
#define hwp3_debug(...) cli_dbgmsg(__VA_ARGS__) |
52 | 57 |
#else |
... | ... |
@@ -85,7 +90,7 @@ static int decompress_and_callback(cli_ctx *ctx, fmap_t *input, off_t at, size_t |
85 | 85 |
|
86 | 86 |
zret = inflateInit2(&zstrm, -15); |
87 | 87 |
if (zret != Z_OK) { |
88 |
- cli_dbgmsg("%s: Can't initialize zlib inflation stream\n", parent); |
|
88 |
+ cli_errmsg("%s: Can't initialize zlib inflation stream\n", parent); |
|
89 | 89 |
ret = CL_EUNPACK; |
90 | 90 |
goto dc_end; |
91 | 91 |
} |
... | ... |
@@ -151,155 +156,6 @@ static int decompress_and_callback(cli_ctx *ctx, fmap_t *input, off_t at, size_t |
151 | 151 |
return ret; |
152 | 152 |
} |
153 | 153 |
|
154 |
-static int decompress_and_scan(int fd, cli_ctx *ctx, int ole2) |
|
155 |
-{ |
|
156 |
- int zret, ofd, ret = CL_SUCCESS; |
|
157 |
- fmap_t *input; |
|
158 |
- off_t off_in = 0; |
|
159 |
- size_t count, outsize = 0; |
|
160 |
-#ifndef HACKNSLASH |
|
161 |
- size_t expect = 0; |
|
162 |
-#endif |
|
163 |
- z_stream zstrm; |
|
164 |
- char *tmpname; |
|
165 |
- unsigned char inbuf[FILEBUFF], outbuf[FILEBUFF]; |
|
166 |
- |
|
167 |
- /* fmap the input file for easier manipulation */ |
|
168 |
- if (fd < 0) { |
|
169 |
- cli_dbgmsg("HWP5.x: Invalid file descriptor argument\n"); |
|
170 |
- return CL_ENULLARG; |
|
171 |
- } else { |
|
172 |
- STATBUF statbuf; |
|
173 |
- |
|
174 |
- if (FSTAT(fd, &statbuf) == -1) { |
|
175 |
- cli_dbgmsg("HWP5.x: Can't stat file descriptor\n"); |
|
176 |
- return CL_ESTAT; |
|
177 |
- } |
|
178 |
- |
|
179 |
- input = fmap(fd, 0, statbuf.st_size); |
|
180 |
- if (!input) { |
|
181 |
- cli_dbgmsg("HWP5.x: Failed to get fmap for input stream\n"); |
|
182 |
- return CL_EMAP; |
|
183 |
- } |
|
184 |
- } |
|
185 |
- |
|
186 |
- /* reserve tempfile for output and scanning */ |
|
187 |
- if ((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &ofd)) != CL_SUCCESS) { |
|
188 |
- cli_errmsg("HWP5.x: Can't generate temporary file\n"); |
|
189 |
- funmap(input); |
|
190 |
- return ret; |
|
191 |
- } |
|
192 |
- |
|
193 |
- /* initialize zlib inflation stream */ |
|
194 |
- memset(&zstrm, 0, sizeof(zstrm)); |
|
195 |
- zstrm.zalloc = Z_NULL; |
|
196 |
- zstrm.zfree = Z_NULL; |
|
197 |
- zstrm.opaque = Z_NULL; |
|
198 |
- zstrm.next_in = inbuf; |
|
199 |
- zstrm.next_out = outbuf; |
|
200 |
- zstrm.avail_in = 0; |
|
201 |
- zstrm.avail_out = FILEBUFF; |
|
202 |
- |
|
203 |
- zret = inflateInit2(&zstrm, -15); |
|
204 |
- if (zret != Z_OK) { |
|
205 |
- cli_dbgmsg("HWP5.x: Can't initialize zlib inflation stream\n"); |
|
206 |
- ret = CL_EUNPACK; |
|
207 |
- goto ds_end; |
|
208 |
- } |
|
209 |
- |
|
210 |
- /* inflation loop */ |
|
211 |
- do { |
|
212 |
- if (zstrm.avail_in == 0) { |
|
213 |
- zstrm.next_in = inbuf; |
|
214 |
- ret = fmap_readn(input, inbuf, off_in, FILEBUFF); |
|
215 |
- if (ret < 0) { |
|
216 |
- cli_errmsg("HWP5.x: Error reading stream\n"); |
|
217 |
- ret = CL_EUNPACK; |
|
218 |
- goto ds_end; |
|
219 |
- } |
|
220 |
- if (!ret) |
|
221 |
- break; |
|
222 |
- |
|
223 |
- zstrm.avail_in = ret; |
|
224 |
- off_in += ret; |
|
225 |
- } |
|
226 |
- zret = inflate(&zstrm, Z_SYNC_FLUSH); |
|
227 |
- count = FILEBUFF - zstrm.avail_out; |
|
228 |
- if (count) { |
|
229 |
- if (cli_checklimits("HWP", ctx, outsize + count, 0, 0) != CL_SUCCESS) |
|
230 |
- break; |
|
231 |
- |
|
232 |
-#ifndef HACKNSLASH |
|
233 |
- /* remove decompressed size uint32_t prefix */ |
|
234 |
- if (ole2) { |
|
235 |
- ole2 = 0; |
|
236 |
- expect = outbuf[0] + (outbuf[1] << 8) + (outbuf[2] << 16) + (outbuf[3] << 24); |
|
237 |
- |
|
238 |
- cli_dbgmsg("HWP5.x: Trimmed OLE2 stream prefix: %08x\n", expect); |
|
239 |
- |
|
240 |
- if (cli_writen(ofd, outbuf+4, count-4) != count-4) { |
|
241 |
- cli_errmsg("HWP5.x: Can't write to file %s\n", tmpname); |
|
242 |
- ret = CL_EWRITE; |
|
243 |
- goto ds_end; |
|
244 |
- } |
|
245 |
- outsize += (count-4); |
|
246 |
- } else { |
|
247 |
-#endif |
|
248 |
- if (cli_writen(ofd, outbuf, count) != count) { |
|
249 |
- cli_errmsg("HWP5.x: Can't write to file %s\n", tmpname); |
|
250 |
- ret = CL_EWRITE; |
|
251 |
- goto ds_end; |
|
252 |
- } |
|
253 |
- outsize += count; |
|
254 |
-#ifndef HACKNSLASH |
|
255 |
- } |
|
256 |
-#endif |
|
257 |
- } |
|
258 |
- zstrm.next_out = outbuf; |
|
259 |
- zstrm.avail_out = FILEBUFF; |
|
260 |
- } while(zret == Z_OK); |
|
261 |
- |
|
262 |
- /* post inflation checks */ |
|
263 |
- if (zret != Z_STREAM_END && zret != Z_OK) { |
|
264 |
- if (outsize == 0) { |
|
265 |
- cli_infomsg(ctx, "HWP5.x: Error decompressing stream. No data decompressed.\n"); |
|
266 |
- ret = CL_EUNPACK; |
|
267 |
- goto ds_end; |
|
268 |
- } |
|
269 |
- |
|
270 |
- cli_infomsg(ctx, "HWP5.x: Error decompressing stream. Scanning what was decompressed.\n"); |
|
271 |
- } |
|
272 |
- cli_dbgmsg("HWP5.x: Decompressed %llu bytes to %s\n", (long long unsigned)outsize, tmpname); |
|
273 |
- |
|
274 |
-#ifndef HACKNSLASH |
|
275 |
- if (expect) { |
|
276 |
- if (outsize != expect) { |
|
277 |
- cli_warnmsg("HWP5.x: declared prefix != inflated stream size, %llu != %llu\n", |
|
278 |
- (long long unsigned)expect, (long long unsigned)outsize); |
|
279 |
- } else { |
|
280 |
- cli_dbgmsg("HWP5.x: declared prefix == inflated stream size, %llu == %llu\n", |
|
281 |
- (long long unsigned)expect, (long long unsigned)outsize); |
|
282 |
- } |
|
283 |
- } |
|
284 |
-#endif |
|
285 |
- |
|
286 |
- /* scanning inflated stream */ |
|
287 |
- ret = cli_magic_scandesc(ofd, ctx); |
|
288 |
- |
|
289 |
- /* clean-up */ |
|
290 |
- ds_end: |
|
291 |
- zret = inflateEnd(&zstrm); |
|
292 |
- if (zret != Z_OK) |
|
293 |
- ret = CL_EUNPACK; |
|
294 |
- close(ofd); |
|
295 |
- if (!ctx->engine->keeptmp) |
|
296 |
- if (cli_unlink(tmpname)) |
|
297 |
- ret = CL_EUNLINK; |
|
298 |
- free(tmpname); |
|
299 |
- funmap(input); |
|
300 |
- return ret; |
|
301 |
-} |
|
302 |
- |
|
303 | 154 |
/*** HWP5 ***/ |
304 | 155 |
|
305 | 156 |
int cli_hwp5header(cli_ctx *ctx, hwp5_header_t *hwp5) |
... | ... |
@@ -372,11 +228,48 @@ int cli_hwp5header(cli_ctx *ctx, hwp5_header_t *hwp5) |
372 | 372 |
return CL_SUCCESS; |
373 | 373 |
} |
374 | 374 |
|
375 |
+static int hwp5_cb(void *cbdata, int fd, cli_ctx *ctx) |
|
376 |
+{ |
|
377 |
+ int ret, ole2 = *(int *)cbdata; |
|
378 |
+ |
|
379 |
+ if (fd < 0 || !ctx) |
|
380 |
+ return CL_ENULLARG; |
|
381 |
+ |
|
382 |
+ /* trim off 32-bit prefix for OLE2 streams */ |
|
383 |
+ if (ole2) { |
|
384 |
+ STATBUF statbuf; |
|
385 |
+ fmap_t *map; |
|
386 |
+ |
|
387 |
+ if (FSTAT(fd, &statbuf) == -1) { |
|
388 |
+ cli_errmsg("HWP5.x: Can't stat file descriptor\n"); |
|
389 |
+ return CL_ESTAT; |
|
390 |
+ } |
|
391 |
+ |
|
392 |
+ map = fmap(fd, 0, statbuf.st_size); |
|
393 |
+ if (!map) { |
|
394 |
+ cli_errmsg("HWP5.x: Failed to get fmap for ole2 stream\n"); |
|
395 |
+ return CL_EMAP; |
|
396 |
+ } |
|
397 |
+ |
|
398 |
+ ret = cli_map_scandesc(map, 4, 0, ctx, CL_TYPE_ANY); |
|
399 |
+ funmap(map); |
|
400 |
+ } else { |
|
401 |
+ ret = cli_magic_scandesc(fd, ctx); |
|
402 |
+ } |
|
403 |
+ |
|
404 |
+ return ret; |
|
405 |
+} |
|
406 |
+ |
|
375 | 407 |
int cli_scanhwp5_stream(cli_ctx *ctx, hwp5_header_t *hwp5, char *name, int fd) |
376 | 408 |
{ |
377 | 409 |
int ole2; |
378 | 410 |
|
379 |
- cli_dbgmsg("HWP5.x: NAME: %s\n", name); |
|
411 |
+ hwp5_debug("HWP5.x: NAME: %s\n", name); |
|
412 |
+ |
|
413 |
+ if (fd < 0) { |
|
414 |
+ cli_errmsg("HWP5.x: Invalid file descriptor argument\n"); |
|
415 |
+ return CL_ENULLARG; |
|
416 |
+ } |
|
380 | 417 |
|
381 | 418 |
/* encrypted and compressed streams */ |
382 | 419 |
if (!strncmp(name, "bin", 3) || !strncmp(name, "jscriptversion", 14) || |
... | ... |
@@ -396,8 +289,26 @@ int cli_scanhwp5_stream(cli_ctx *ctx, hwp5_header_t *hwp5, char *name, int fd) |
396 | 396 |
|
397 | 397 |
if (hwp5->flags & HWP5_COMPRESSED) { |
398 | 398 |
/* DocInfo JSON Handling */ |
399 |
- cli_dbgmsg("HWP5.x: Sending %s for decompress and scan\n", name); |
|
400 |
- return decompress_and_scan(fd, ctx, ole2); |
|
399 |
+ STATBUF statbuf; |
|
400 |
+ fmap_t *input; |
|
401 |
+ int ret; |
|
402 |
+ |
|
403 |
+ hwp5_debug("HWP5.x: Sending %s for decompress and scan\n", name); |
|
404 |
+ |
|
405 |
+ /* fmap the input file for easier manipulation */ |
|
406 |
+ if (FSTAT(fd, &statbuf) == -1) { |
|
407 |
+ cli_errmsg("HWP5.x: Can't stat file descriptor\n"); |
|
408 |
+ return CL_ESTAT; |
|
409 |
+ } |
|
410 |
+ |
|
411 |
+ input = fmap(fd, 0, statbuf.st_size); |
|
412 |
+ if (!input) { |
|
413 |
+ cli_errmsg("HWP5.x: Failed to get fmap for input stream\n"); |
|
414 |
+ return CL_EMAP; |
|
415 |
+ } |
|
416 |
+ ret = decompress_and_callback(ctx, input, 0, 0, "HWP5.x", hwp5_cb, &ole2); |
|
417 |
+ funmap(input); |
|
418 |
+ return ret; |
|
401 | 419 |
} |
402 | 420 |
} |
403 | 421 |
|
... | ... |
@@ -469,7 +380,7 @@ static inline int parsehwp3_docinfo(cli_ctx *ctx, off_t offset, struct hwp3_doci |
469 | 469 |
|
470 | 470 |
//TODO: use fmap_readn? |
471 | 471 |
if (!(hwp3_ptr = fmap_need_off_once(*ctx->fmap, offset, HWP3_DOCINFO_SIZE))) { |
472 |
- cli_dbgmsg("HWP3.x: Failed to read fmap for hwp docinfo\n"); |
|
472 |
+ cli_errmsg("HWP3.x: Failed to read fmap for hwp docinfo\n"); |
|
473 | 473 |
return CL_EMAP; |
474 | 474 |
} |
475 | 475 |
|
... | ... |
@@ -529,7 +440,7 @@ static inline int parsehwp3_docsummary(cli_ctx *ctx, off_t offset) |
529 | 529 |
json_object *summary; |
530 | 530 |
|
531 | 531 |
if (!(hwp3_ptr = fmap_need_off_once(*ctx->fmap, offset, HWP3_DOCSUMMARY_SIZE))) { |
532 |
- cli_dbgmsg("HWP3.x: Failed to read fmap for hwp docinfo\n"); |
|
532 |
+ cli_errmsg("HWP3.x: Failed to read fmap for hwp docinfo\n"); |
|
533 | 533 |
return CL_EMAP; |
534 | 534 |
} |
535 | 535 |
|
... | ... |
@@ -617,19 +528,19 @@ static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx) |
617 | 617 |
uint16_t nstyles; |
618 | 618 |
|
619 | 619 |
if (fd < 0) { |
620 |
- cli_dbgmsg("HWP3.x: Invalid file descriptor argument\n"); |
|
620 |
+ cli_errmsg("HWP3.x: Invalid file descriptor argument\n"); |
|
621 | 621 |
return CL_ENULLARG; |
622 | 622 |
} else { |
623 | 623 |
STATBUF statbuf; |
624 | 624 |
|
625 | 625 |
if (FSTAT(fd, &statbuf) == -1) { |
626 |
- cli_dbgmsg("HWP3.x: Can't stat file descriptor\n"); |
|
626 |
+ cli_errmsg("HWP3.x: Can't stat file descriptor\n"); |
|
627 | 627 |
return CL_ESTAT; |
628 | 628 |
} |
629 | 629 |
|
630 | 630 |
dmap = fmap(fd, 0, statbuf.st_size); |
631 | 631 |
if (!dmap) { |
632 |
- cli_dbgmsg("HWP3.x: Failed to get fmap for uncompressed stream\n"); |
|
632 |
+ cli_errmsg("HWP3.x: Failed to get fmap for uncompressed stream\n"); |
|
633 | 633 |
return CL_EMAP; |
634 | 634 |
} |
635 | 635 |
} |
... | ... |
@@ -665,11 +576,10 @@ static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx) |
665 | 665 |
|
666 | 666 |
/* Additional Information Block (Internal) - Attachments and Media */ |
667 | 667 |
|
668 |
- funmap(dmap); |
|
669 |
- |
|
670 | 668 |
/* scan the uncompressed stream? */ |
671 |
- //ret = cli_magic_scandesc(fd, ctx); |
|
669 |
+ //ret = cli_map_scandesc(dmap, 0, 0, ctx, CL_TYPE_ANY); |
|
672 | 670 |
|
671 |
+ funmap(dmap); |
|
673 | 672 |
return ret; |
674 | 673 |
} |
675 | 674 |
|