git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@312 77e5149b-7576-45b1-b177-96237e5ba77b
Trog authored on 2004/02/20 01:00:05... | ... |
@@ -1,4 +1,9 @@ |
1 |
+Thu Feb 19 16:03:59 GMT 2004 (trog) |
|
2 |
+----------------------------------- |
|
3 |
+ * libclamav/vba_extract.c: tidy up error handling |
|
4 |
+ |
|
1 | 5 |
Thu Feb 19 12:16:33 CET 2004 (tl) |
6 |
+--------------------------------- |
|
2 | 7 |
* freshclam: + write pid file if run as daemon (new option -p|--pid) |
3 | 8 |
+ handle signals: HUP = re-open logfiles |
4 | 9 |
TERM = terminate (with log message) |
... | ... |
@@ -251,13 +251,16 @@ vba_project_t *vba56_dir_read(const char *dir) |
251 | 251 |
free(fullname); |
252 | 252 |
|
253 | 253 |
if (vba_readn(fd, &magic, 2) != 2) { |
254 |
+ close(fd); |
|
254 | 255 |
return NULL; |
255 | 256 |
} |
256 | 257 |
if (memcmp(magic, vba56_signature, 2) != 0) { |
258 |
+ close(fd); |
|
257 | 259 |
return NULL; |
258 | 260 |
} |
259 | 261 |
|
260 | 262 |
if (vba_readn(fd, &version, 4) != 4) { |
263 |
+ close(fd); |
|
261 | 264 |
return NULL; |
262 | 265 |
} |
263 | 266 |
for (i=0 ; i < NUM_VBA_VERSIONS ; i++) { |
... | ... |
@@ -269,6 +272,7 @@ vba_project_t *vba56_dir_read(const char *dir) |
269 | 269 |
if (i == NUM_VBA_VERSIONS) { |
270 | 270 |
cli_dbgmsg("Unknown VBA version signature x0%x0x%x0x%x0x%x\n", |
271 | 271 |
version[0], version[1], version[2], version[3]); |
272 |
+ close(fd); |
|
272 | 273 |
return NULL; |
273 | 274 |
} |
274 | 275 |
|
... | ... |
@@ -280,38 +284,48 @@ vba_project_t *vba56_dir_read(const char *dir) |
280 | 280 |
|
281 | 281 |
/* two bytes, should be equal to 0x00ff */ |
282 | 282 |
if (vba_readn(fd, &ooff, 2) != 2) { |
283 |
+ close(fd); |
|
283 | 284 |
return NULL; |
284 | 285 |
} |
285 | 286 |
|
286 | 287 |
if (vba_readn(fd, &LidA, 4) != 4) { |
288 |
+ close(fd); |
|
287 | 289 |
return NULL; |
288 | 290 |
} |
289 | 291 |
|
290 | 292 |
if (vba_readn(fd, &LidA, 4) != 4) { |
293 |
+ close(fd); |
|
291 | 294 |
return NULL; |
292 | 295 |
} |
293 | 296 |
|
294 | 297 |
if (vba_readn(fd, &CharSet, 2) != 2) { |
298 |
+ close(fd); |
|
295 | 299 |
return NULL; |
296 | 300 |
} |
297 | 301 |
if (vba_readn(fd, &LenA, 2) != 2) { |
302 |
+ close(fd); |
|
298 | 303 |
return NULL; |
299 | 304 |
} |
300 | 305 |
|
301 | 306 |
if (vba_readn(fd, &UnknownB, 4) != 4) { |
307 |
+ close(fd); |
|
302 | 308 |
return NULL; |
303 | 309 |
} |
304 | 310 |
if (vba_readn(fd, &UnknownC, 4) != 4) { |
311 |
+ close(fd); |
|
305 | 312 |
return NULL; |
306 | 313 |
} |
307 | 314 |
|
308 | 315 |
if (vba_readn(fd, &LenB, 2) != 2) { |
316 |
+ close(fd); |
|
309 | 317 |
return NULL; |
310 | 318 |
} |
311 | 319 |
if (vba_readn(fd, &LenC, 2) != 2) { |
320 |
+ close(fd); |
|
312 | 321 |
return NULL; |
313 | 322 |
} |
314 | 323 |
if (vba_readn(fd, &LenD, 2) != 2) { |
324 |
+ close(fd); |
|
315 | 325 |
return NULL; |
316 | 326 |
} |
317 | 327 |
|
... | ... |
@@ -334,16 +348,19 @@ vba_project_t *vba56_dir_read(const char *dir) |
334 | 334 |
/* read the rest of the header. most of this is unknown */ |
335 | 335 |
/* buff = (char *) cli_malloc(24); |
336 | 336 |
if (!buff || vba_readn(fd, buff, 24) != 24) { |
337 |
+ close(fd); |
|
337 | 338 |
return NULL; |
338 | 339 |
} |
339 | 340 |
free(buff); |
340 | 341 |
|
341 | 342 |
if (vba_readn(fd, &record_count, 2) != 2) { |
343 |
+ close(fd); |
|
342 | 344 |
return NULL; |
343 | 345 |
} |
344 | 346 |
cli_dbgmsg("Record count: %d\n", record_count); */ |
345 | 347 |
/* read two bytes and throw them away */ |
346 | 348 |
/* if (vba_readn(fd, &length, 2) != 2) { |
349 |
+ close(fd); |
|
347 | 350 |
return NULL; |
348 | 351 |
}*/ |
349 | 352 |
|
... | ... |
@@ -361,10 +378,12 @@ vba_project_t *vba56_dir_read(const char *dir) |
361 | 361 |
buff = (unsigned char *) cli_malloc(length); |
362 | 362 |
if (!buff) { |
363 | 363 |
cli_errmsg("cli_malloc failed\n"); |
364 |
+ close(fd); |
|
364 | 365 |
return NULL; |
365 | 366 |
} |
366 | 367 |
if (vba_readn(fd, buff, length) != length) { |
367 | 368 |
cli_errmsg("read name failed\n"); |
369 |
+ close(fd); |
|
368 | 370 |
return NULL; |
369 | 371 |
} |
370 | 372 |
name = get_unicode_name(buff, length); |
... | ... |
@@ -381,6 +400,7 @@ vba_project_t *vba56_dir_read(const char *dir) |
381 | 381 |
cli_errmsg("failed to read blob\n"); |
382 | 382 |
free(buff); |
383 | 383 |
free(name); |
384 |
+ close(fd); |
|
384 | 385 |
return NULL; |
385 | 386 |
} |
386 | 387 |
free(buff); |
... | ... |
@@ -391,6 +411,7 @@ vba_project_t *vba56_dir_read(const char *dir) |
391 | 391 |
cli_errmsg("failed to read blob\n"); |
392 | 392 |
free(buff); |
393 | 393 |
free(name); |
394 |
+ close(fd); |
|
394 | 395 |
return NULL; |
395 | 396 |
} |
396 | 397 |
free(buff); |
... | ... |
@@ -413,11 +434,13 @@ vba_project_t *vba56_dir_read(const char *dir) |
413 | 413 |
vba56_test_end(fd); |
414 | 414 |
|
415 | 415 |
if (vba_readn(fd, &record_count, 2) != 2) { |
416 |
+ close(fd); |
|
416 | 417 |
return NULL; |
417 | 418 |
} |
418 | 419 |
record_count = vba_endian_convert_16(record_count); |
419 | 420 |
cli_dbgmsg("\nVBA Record count: %d\n", record_count); |
420 | 421 |
/*if (record_count <= 0) { |
422 |
+ close(fd); |
|
421 | 423 |
return TRUE; |
422 | 424 |
}*/ |
423 | 425 |
|
... | ... |
@@ -427,14 +450,17 @@ vba_project_t *vba56_dir_read(const char *dir) |
427 | 427 |
/* Read fixed octet */ |
428 | 428 |
buff = (unsigned char *) cli_malloc(8); |
429 | 429 |
if (!buff) { |
430 |
+ close(fd); |
|
430 | 431 |
return NULL; |
431 | 432 |
} |
432 | 433 |
if (vba_readn(fd, buff, 8) != 8) { |
433 | 434 |
free(buff); |
435 |
+ close(fd); |
|
434 | 436 |
return NULL; |
435 | 437 |
} |
436 | 438 |
if (!memcmp(buff, fixed_octet, 8)) { |
437 | 439 |
free(buff); |
440 |
+ close(fd); |
|
438 | 441 |
return NULL; |
439 | 442 |
} |
440 | 443 |
free(buff); |
... | ... |
@@ -443,11 +469,13 @@ vba_project_t *vba56_dir_read(const char *dir) |
443 | 443 |
/* junk some more stuff */ |
444 | 444 |
do { |
445 | 445 |
if (vba_readn(fd, &ooff, 2) != 2) { |
446 |
+ close(fd); |
|
446 | 447 |
return NULL; |
447 | 448 |
} |
448 | 449 |
} while(ooff != 0xFFFF); |
449 | 450 |
|
450 | 451 |
if (vba_readn(fd, &ooff, 2) != 2) { |
452 |
+ close(fd); |
|
451 | 453 |
return NULL; |
452 | 454 |
} |
453 | 455 |
|
... | ... |
@@ -457,6 +485,7 @@ vba_project_t *vba56_dir_read(const char *dir) |
457 | 457 |
lseek(fd, ooff, SEEK_CUR); |
458 | 458 |
} |
459 | 459 |
if (vba_readn(fd, &ooff, 2) != 2) { |
460 |
+ close(fd); |
|
460 | 461 |
return NULL; |
461 | 462 |
} |
462 | 463 |
if (ooff != 0xFFFF) { |
... | ... |
@@ -466,6 +495,7 @@ vba_project_t *vba56_dir_read(const char *dir) |
466 | 466 |
lseek(fd, 100, SEEK_CUR); |
467 | 467 |
|
468 | 468 |
if (vba_readn(fd, &record_count, 2) != 2) { |
469 |
+ close(fd); |
|
469 | 470 |
return NULL; |
470 | 471 |
} |
471 | 472 |
record_count = vba_endian_convert_16(record_count); |
... | ... |
@@ -479,17 +509,18 @@ vba_project_t *vba56_dir_read(const char *dir) |
479 | 479 |
vba_project->count = record_count; |
480 | 480 |
for (i=0 ; i < record_count ; i++) { |
481 | 481 |
if (vba_readn(fd, &length, 2) != 2) { |
482 |
- return NULL; |
|
482 |
+ goto out_error; |
|
483 | 483 |
} |
484 | 484 |
length = vba_endian_convert_16(length); |
485 | 485 |
buff = (unsigned char *) cli_malloc(length); |
486 | 486 |
if (!buff) { |
487 | 487 |
cli_dbgmsg("cli_malloc failed\n"); |
488 |
- return NULL; |
|
488 |
+ goto out_error; |
|
489 | 489 |
} |
490 | 490 |
if (vba_readn(fd, buff, length) != length) { |
491 | 491 |
cli_dbgmsg("read name failed\n"); |
492 |
- return NULL; |
|
492 |
+ free(buff); |
|
493 |
+ goto out_error; |
|
493 | 494 |
} |
494 | 495 |
vba_project->name[i] = get_unicode_name(buff, length); |
495 | 496 |
cli_dbgmsg("project name: %s, ", vba_project->name[i]); |
... | ... |
@@ -497,20 +528,23 @@ vba_project_t *vba56_dir_read(const char *dir) |
497 | 497 |
|
498 | 498 |
/* some kind of string identifier ?? */ |
499 | 499 |
if (vba_readn(fd, &length, 2) != 2) { |
500 |
- return NULL; |
|
500 |
+ free(vba_project->name[i]); |
|
501 |
+ goto out_error; |
|
501 | 502 |
} |
502 | 503 |
length = vba_endian_convert_16(length); |
503 | 504 |
lseek(fd, length, SEEK_CUR); |
504 | 505 |
|
505 | 506 |
/* unknown stuff */ |
506 | 507 |
if (vba_readn(fd, &ooff, 2) != 2) { |
507 |
- return NULL; |
|
508 |
+ free(vba_project->name[i]); |
|
509 |
+ goto out_error; |
|
508 | 510 |
} |
509 | 511 |
ooff = vba_endian_convert_16(ooff); |
510 | 512 |
if (ooff == 0xFFFF) { |
511 | 513 |
lseek(fd, 2, SEEK_CUR); |
512 | 514 |
if (vba_readn(fd, &ooff, 2) != 2) { |
513 |
- return NULL; |
|
515 |
+ free(vba_project->name[i]); |
|
516 |
+ goto out_error; |
|
514 | 517 |
} |
515 | 518 |
ooff = vba_endian_convert_16(ooff); |
516 | 519 |
lseek(fd, ooff, SEEK_CUR); |
... | ... |
@@ -520,14 +554,16 @@ vba_project_t *vba56_dir_read(const char *dir) |
520 | 520 |
|
521 | 521 |
lseek(fd, 8, SEEK_CUR); |
522 | 522 |
if (vba_readn(fd, &byte_count, 1) != 1) { |
523 |
- return NULL; |
|
523 |
+ free(vba_project->name[i]); |
|
524 |
+ goto out_error; |
|
524 | 525 |
} |
525 | 526 |
for (j=0 ; j<byte_count; j++) { |
526 | 527 |
lseek(fd, 8, SEEK_CUR); |
527 | 528 |
} |
528 | 529 |
lseek(fd, 6, SEEK_CUR); |
529 | 530 |
if (vba_readn(fd, &offset, 4) != 4) { |
530 |
- return NULL; |
|
531 |
+ free(vba_project->name[i]); |
|
532 |
+ goto out_error; |
|
531 | 533 |
} |
532 | 534 |
offset = vba_endian_convert_32(offset); |
533 | 535 |
vba_project->offset[i] = offset; |
... | ... |
@@ -545,6 +581,19 @@ vba_project_t *vba56_dir_read(const char *dir) |
545 | 545 |
} |
546 | 546 |
close(fd); |
547 | 547 |
return vba_project; |
548 |
+ |
|
549 |
+out_error: |
|
550 |
+ /* Note: only to be called from the above loop |
|
551 |
+ when i == number of allocated stings */ |
|
552 |
+ for (j=0 ; j<i ; j++) { |
|
553 |
+ free(vba_project->name[j]); |
|
554 |
+ } |
|
555 |
+ free(vba_project->name); |
|
556 |
+ free(vba_project->dir); |
|
557 |
+ free(vba_project->offset); |
|
558 |
+ free(vba_project); |
|
559 |
+ close(fd); |
|
560 |
+ return NULL; |
|
548 | 561 |
} |
549 | 562 |
|
550 | 563 |
#define VBA_COMPRESSION_WINDOW 4096 |
... | ... |
@@ -554,10 +603,10 @@ void byte_array_append(byte_array_t *array, unsigned char *src, unsigned int len |
554 | 554 |
if (array->length == 0) { |
555 | 555 |
array->data = (unsigned char *) cli_malloc(len); |
556 | 556 |
array->length = len; |
557 |
- strncpy(array->data, src, len); |
|
557 |
+ memcpy(array->data, src, len); |
|
558 | 558 |
} else { |
559 | 559 |
array->data = realloc(array->data, array->length+len); |
560 |
- strncpy(array->data+array->length, src, len); |
|
560 |
+ memcpy(array->data+array->length, src, len); |
|
561 | 561 |
array->length += len; |
562 | 562 |
} |
563 | 563 |
} |
... | ... |
@@ -579,7 +628,10 @@ unsigned char *vba_decompress(int fd, uint32_t offset) |
579 | 579 |
for (mask = 1; mask < 0x100; mask<<=1) { |
580 | 580 |
if (flag & mask) { |
581 | 581 |
if (vba_readn(fd, &token, 2) != 2) { |
582 |
- return FALSE; |
|
582 |
+ if (result.data) { |
|
583 |
+ free(result.data); |
|
584 |
+ } |
|
585 |
+ return NULL; |
|
583 | 586 |
} |
584 | 587 |
token = vba_endian_convert_16(token); |
585 | 588 |
win_pos = pos % VBA_COMPRESSION_WINDOW; |
... | ... |
@@ -615,7 +667,10 @@ unsigned char *vba_decompress(int fd, uint32_t offset) |
615 | 615 |
((pos % VBA_COMPRESSION_WINDOW) == 0) && clean) { |
616 | 616 |
|
617 | 617 |
if (vba_readn(fd, &token, 2) != 2) { |
618 |
- return FALSE; |
|
618 |
+ if (result.data) { |
|
619 |
+ free(result.data); |
|
620 |
+ } |
|
621 |
+ return NULL; |
|
619 | 622 |
} |
620 | 623 |
clean = FALSE; |
621 | 624 |
byte_array_append(&result, buffer, VBA_COMPRESSION_WINDOW); |
... | ... |
@@ -632,6 +687,7 @@ unsigned char *vba_decompress(int fd, uint32_t offset) |
632 | 632 |
if (pos % VBA_COMPRESSION_WINDOW) { |
633 | 633 |
byte_array_append(&result, buffer, pos % VBA_COMPRESSION_WINDOW); |
634 | 634 |
} |
635 |
+ byte_array_append(&result, "\0", 1); |
|
635 | 636 |
return result.data; |
636 | 637 |
|
637 | 638 |
} |