git-svn: trunk@3382
Tomasz Kojm authored on 2007/12/07 00:25:50... | ... |
@@ -84,10 +84,6 @@ |
84 | 84 |
#endif |
85 | 85 |
|
86 | 86 |
#define GARBLE_FLAG 0x01 |
87 |
-#define VOLUME_FLAG 0x04 |
|
88 |
-#define EXTFILE_FLAG 0x08 |
|
89 |
-#define PATHSYM_FLAG 0x10 |
|
90 |
-#define BACKUP_FLAG 0x20 |
|
91 | 87 |
|
92 | 88 |
#ifndef HAVE_ATTRIB_PACKED |
93 | 89 |
#define __attribute__(x) |
... | ... |
@@ -382,9 +378,17 @@ static int read_c_len(arj_decode_t *decode_data) |
382 | 382 |
c = arj_getbits(decode_data, CBIT) + 20; |
383 | 383 |
} |
384 | 384 |
while (--c >= 0) { |
385 |
+ if (i >= NC) { |
|
386 |
+ cli_warnmsg("ERROR: bounds exceeded\n"); |
|
387 |
+ return CL_EFORMAT; |
|
388 |
+ } |
|
385 | 389 |
decode_data->c_len[i++] = 0; |
386 | 390 |
} |
387 | 391 |
} else { |
392 |
+ if (i >= NC) { |
|
393 |
+ cli_warnmsg("ERROR: bounds exceeded\n"); |
|
394 |
+ return CL_EFORMAT; |
|
395 |
+ } |
|
388 | 396 |
decode_data->c_len[i++] = (unsigned char) (c - 2); |
389 | 397 |
} |
390 | 398 |
} |
... | ... |
@@ -495,7 +499,7 @@ static int decode(int fd, arj_metadata_t *metadata) |
495 | 495 |
break; |
496 | 496 |
} |
497 | 497 |
if (out_ptr > i && out_ptr < DDICSIZ - MAXMATCH - 1) { |
498 |
- while ((--j >= 0) && (i < DDICSIZ)) { |
|
498 |
+ while ((--j >= 0) && (i < DDICSIZ) && (out_ptr < DDICSIZ)) { |
|
499 | 499 |
decode_data.text[out_ptr++] = decode_data.text[i++]; |
500 | 500 |
} |
501 | 501 |
} else { |
... | ... |
@@ -629,7 +633,7 @@ static int decode_f(int fd, arj_metadata_t *metadata) |
629 | 629 |
return CL_SUCCESS; |
630 | 630 |
} |
631 | 631 |
|
632 |
-static uint32_t arj_unstore(int ifd, int ofd, uint64_t len) |
|
632 |
+static uint32_t arj_unstore(int ifd, int ofd, uint32_t len) |
|
633 | 633 |
{ |
634 | 634 |
unsigned char data[8192]; |
635 | 635 |
uint32_t count, rem; |
... | ... |
@@ -639,7 +643,7 @@ static uint32_t arj_unstore(int ifd, int ofd, uint64_t len) |
639 | 639 |
rem = len; |
640 | 640 |
|
641 | 641 |
while (rem > 0) { |
642 |
- todo = MIN(8192, rem); |
|
642 |
+ todo = (unsigned int) MIN(8192, rem); |
|
643 | 643 |
count = cli_readn(ifd, data, todo); |
644 | 644 |
if (count != todo) { |
645 | 645 |
return len-rem; |
... | ... |
@@ -683,7 +687,7 @@ static int arj_read_main_header(int fd) |
683 | 683 |
cli_dbgmsg("Header Size: %d\n", header_size); |
684 | 684 |
if (header_size == 0) { |
685 | 685 |
/* End of archive */ |
686 |
- return 0; |
|
686 |
+ return FALSE; |
|
687 | 687 |
} |
688 | 688 |
if (header_size > HEADERSIZE_MAX) { |
689 | 689 |
cli_dbgmsg("arj_read_header: invalid header_size: %u\n ", header_size); |
... | ... |
@@ -693,13 +697,6 @@ static int arj_read_main_header(int fd) |
693 | 693 |
if (cli_readn(fd, &main_hdr, 30) != 30) { |
694 | 694 |
return FALSE; |
695 | 695 |
} |
696 |
- main_hdr.time_created = le32_to_host(main_hdr.time_created); |
|
697 |
- main_hdr.time_modified = le32_to_host(main_hdr.time_modified); |
|
698 |
- main_hdr.archive_size = le32_to_host(main_hdr.archive_size); |
|
699 |
- main_hdr.sec_env_file_position = le32_to_host(main_hdr.sec_env_file_position); |
|
700 |
- main_hdr.entryname_pos = le16_to_host(main_hdr.entryname_pos); |
|
701 |
- main_hdr.sec_trail_size = le16_to_host(main_hdr.sec_trail_size); |
|
702 |
- main_hdr.host_data = le16_to_host(main_hdr.host_data); |
|
703 | 696 |
|
704 | 697 |
cli_dbgmsg("ARJ Main File Header\n"); |
705 | 698 |
cli_dbgmsg("First Header Size: %d\n", main_hdr.first_hdr_size); |
... | ... |
@@ -709,23 +706,21 @@ static int arj_read_main_header(int fd) |
709 | 709 |
cli_dbgmsg("Flags: 0x%x\n", main_hdr.flags); |
710 | 710 |
cli_dbgmsg("Security version: %d\n", main_hdr.security_version); |
711 | 711 |
cli_dbgmsg("File type: %d\n", main_hdr.file_type); |
712 |
- cli_dbgmsg("Time created: %lu\n", main_hdr.time_created); |
|
713 |
- cli_dbgmsg("Time modified: %lu\n", main_hdr.time_modified); |
|
714 |
- cli_dbgmsg("Archive size: %lu\n", main_hdr.archive_size); |
|
715 |
- cli_dbgmsg("Security envelope file pos: %lu\n", main_hdr.archive_size); |
|
716 |
- cli_dbgmsg("Entryname pos: %u\n", main_hdr.entryname_pos); |
|
717 |
- cli_dbgmsg("Security trailer size: %u\n", main_hdr.sec_trail_size); |
|
718 |
- cli_dbgmsg("Host data: %u\n\n", main_hdr.host_data); |
|
719 | 712 |
|
720 | 713 |
if (main_hdr.first_hdr_size < 30) { |
721 | 714 |
cli_dbgmsg("Format error. First Header Size < 30\n"); |
722 | 715 |
return FALSE; |
723 | 716 |
} |
724 | 717 |
if (main_hdr.first_hdr_size > 30) { |
725 |
- lseek(fd, main_hdr.first_hdr_size - 30, SEEK_CUR); |
|
718 |
+ if (lseek(fd, main_hdr.first_hdr_size - 30, SEEK_CUR) == -1) { |
|
719 |
+ return FALSE; |
|
720 |
+ } |
|
726 | 721 |
} |
727 | 722 |
|
728 | 723 |
filename = (char *) cli_malloc(header_size); |
724 |
+ if (!filename) { |
|
725 |
+ return FALSE; |
|
726 |
+ } |
|
729 | 727 |
for (count=0 ; count < header_size ; count++) { |
730 | 728 |
if (cli_readn(fd, &filename[count], 1) != 1) { |
731 | 729 |
free(filename); |
... | ... |
@@ -740,6 +735,10 @@ static int arj_read_main_header(int fd) |
740 | 740 |
return FALSE; |
741 | 741 |
} |
742 | 742 |
comment = (char *) cli_malloc(header_size); |
743 |
+ if (!comment) { |
|
744 |
+ free(filename); |
|
745 |
+ return FALSE; |
|
746 |
+ } |
|
743 | 747 |
for (count=0 ; count < header_size ; count++) { |
744 | 748 |
if (cli_readn(fd, &comment[count], 1) != 1) { |
745 | 749 |
free(filename); |
... | ... |
@@ -771,11 +770,12 @@ static int arj_read_main_header(int fd) |
771 | 771 |
return FALSE; |
772 | 772 |
} |
773 | 773 |
count = le16_to_host(count); |
774 |
- cli_dbgmsg("Count: %d\n", count); |
|
774 |
+ cli_dbgmsg("Extended header size: %d\n", count); |
|
775 | 775 |
if (count == 0) { |
776 | 776 |
break; |
777 | 777 |
} |
778 |
- if (lseek(fd, (off_t) (count + 4), SEEK_CUR) != (count + 4)) { |
|
778 |
+ /* Skip extended header + 4byte CRC */ |
|
779 |
+ if (lseek(fd, (off_t) (count + 4), SEEK_CUR) == -1) { |
|
779 | 780 |
return FALSE; |
780 | 781 |
} |
781 | 782 |
} |
... | ... |
@@ -805,13 +805,8 @@ static int arj_read_file_header(int fd, arj_metadata_t *metadata) |
805 | 805 |
if (cli_readn(fd, &file_hdr, 30) != 30) { |
806 | 806 |
return CL_EFORMAT; |
807 | 807 |
} |
808 |
- file_hdr.time_modified = le32_to_host(file_hdr.time_modified); |
|
809 | 808 |
file_hdr.comp_size = le32_to_host(file_hdr.comp_size); |
810 | 809 |
file_hdr.orig_size = le32_to_host(file_hdr.orig_size); |
811 |
- file_hdr.orig_crc = le32_to_host(file_hdr.orig_crc); |
|
812 |
- file_hdr.entryname_pos = le16_to_host(file_hdr.entryname_pos); |
|
813 |
- file_hdr.file_mode = le16_to_host(file_hdr.file_mode); |
|
814 |
- file_hdr.host_data = le16_to_host(file_hdr.host_data); |
|
815 | 810 |
|
816 | 811 |
cli_dbgmsg("ARJ File Header\n"); |
817 | 812 |
cli_dbgmsg("First Header Size: %d\n", file_hdr.first_hdr_size); |
... | ... |
@@ -822,23 +817,25 @@ static int arj_read_file_header(int fd, arj_metadata_t *metadata) |
822 | 822 |
cli_dbgmsg("Method: %d\n", file_hdr.method); |
823 | 823 |
cli_dbgmsg("File type: %d\n", file_hdr.file_type); |
824 | 824 |
cli_dbgmsg("File type: %d\n", file_hdr.password_mod); |
825 |
- cli_dbgmsg("Time modified: %lu\n", file_hdr.time_modified); |
|
826 |
- cli_dbgmsg("Compressed size: %lu\n", file_hdr.comp_size); |
|
827 |
- cli_dbgmsg("Original size: %lu\n", file_hdr.orig_size); |
|
828 |
- cli_dbgmsg("Original crc: %lu\n", file_hdr.orig_crc); |
|
829 |
- cli_dbgmsg("Entryname pos: %u\n", file_hdr.entryname_pos); |
|
830 |
- cli_dbgmsg("File access mode: %u\n", file_hdr.file_mode); |
|
831 |
- cli_dbgmsg("Host data: %u\n\n", file_hdr.host_data); |
|
825 |
+ cli_dbgmsg("Compressed size: %u\n", file_hdr.comp_size); |
|
826 |
+ cli_dbgmsg("Original size: %u\n", file_hdr.orig_size); |
|
832 | 827 |
|
833 | 828 |
if (file_hdr.first_hdr_size < 30) { |
834 | 829 |
cli_dbgmsg("Format error. First Header Size < 30\n"); |
835 | 830 |
return CL_EFORMAT; |
836 | 831 |
} |
832 |
+ |
|
833 |
+ /* Note: this skips past any extended file start position data (multi-volume) */ |
|
837 | 834 |
if (file_hdr.first_hdr_size > 30) { |
838 |
- lseek(fd, file_hdr.first_hdr_size - 30, SEEK_CUR); |
|
835 |
+ if (lseek(fd, file_hdr.first_hdr_size - 30, SEEK_CUR) == -1) { |
|
836 |
+ return CL_EFORMAT; |
|
837 |
+ } |
|
839 | 838 |
} |
840 | 839 |
|
841 | 840 |
filename = (char *) cli_malloc(header_size); |
841 |
+ if (!filename) { |
|
842 |
+ return CL_EMEM; |
|
843 |
+ } |
|
842 | 844 |
for (count=0 ; count < header_size ; count++) { |
843 | 845 |
if (cli_readn(fd, &filename[count], 1) != 1) { |
844 | 846 |
free(filename); |
... | ... |
@@ -854,6 +851,10 @@ static int arj_read_file_header(int fd, arj_metadata_t *metadata) |
854 | 854 |
} |
855 | 855 |
|
856 | 856 |
comment = (char *) cli_malloc(header_size); |
857 |
+ if (!comment) { |
|
858 |
+ free(filename); |
|
859 |
+ return CL_EFORMAT; |
|
860 |
+ } |
|
857 | 861 |
for (count=0 ; count < header_size ; count++) { |
858 | 862 |
if (cli_readn(fd, &comment[count], 1) != 1) { |
859 | 863 |
free(filename); |
... | ... |
@@ -875,8 +876,9 @@ static int arj_read_file_header(int fd, arj_metadata_t *metadata) |
875 | 875 |
|
876 | 876 |
free(filename); |
877 | 877 |
free(comment); |
878 |
- |
|
879 |
- if (cli_readn(fd, &metadata->crc, 4) != 4) { |
|
878 |
+ |
|
879 |
+ /* Skip CRC */ |
|
880 |
+ if (lseek(fd, (off_t) 4, SEEK_CUR) == -1) { |
|
880 | 881 |
return CL_EFORMAT; |
881 | 882 |
} |
882 | 883 |
|
... | ... |
@@ -886,22 +888,19 @@ static int arj_read_file_header(int fd, arj_metadata_t *metadata) |
886 | 886 |
return CL_EFORMAT; |
887 | 887 |
} |
888 | 888 |
count = le16_to_host(count); |
889 |
- cli_dbgmsg("Count: %d\n", count); |
|
889 |
+ cli_dbgmsg("Extended header size: %d\n", count); |
|
890 | 890 |
if (count == 0) { |
891 | 891 |
break; |
892 | 892 |
} |
893 |
- if (lseek(fd, (off_t) (count + 4), SEEK_CUR) != (count + 4)) { |
|
893 |
+ /* Skip extended header + 4byte CRC */ |
|
894 |
+ if (lseek(fd, (off_t) (count + 4), SEEK_CUR) == -1) { |
|
894 | 895 |
return CL_EFORMAT; |
895 | 896 |
} |
896 | 897 |
} |
897 |
- metadata->min_version = file_hdr.min_version; |
|
898 | 898 |
metadata->comp_size = file_hdr.comp_size; |
899 | 899 |
metadata->orig_size = file_hdr.orig_size; |
900 |
- metadata->orig_crc = file_hdr.orig_crc; |
|
901 |
- metadata->host_os = file_hdr.host_os; |
|
902 |
- metadata->flags = file_hdr.flags; |
|
903 | 900 |
metadata->method = file_hdr.method; |
904 |
- metadata->encrypted = ((metadata->flags & GARBLE_FLAG) != 0) ? TRUE : FALSE; |
|
901 |
+ metadata->encrypted = ((file_hdr.flags & GARBLE_FLAG) != 0) ? TRUE : FALSE; |
|
905 | 902 |
metadata->ofd = -1; |
906 | 903 |
if (!metadata->filename) { |
907 | 904 |
return CL_EMEM; |
... | ... |
@@ -928,8 +927,10 @@ int cli_unarj_open(int fd, const char *dirname) |
928 | 928 |
|
929 | 929 |
int cli_unarj_prepare_file(int fd, const char *dirname, arj_metadata_t *metadata) |
930 | 930 |
{ |
931 |
- |
|
932 | 931 |
cli_dbgmsg("in cli_unarj_prepare_file\n"); |
932 |
+ if (!metadata || !dirname || (fd < 0)) { |
|
933 |
+ return CL_ENULLARG; |
|
934 |
+ } |
|
933 | 935 |
/* Each file is preceeded by the ARJ file marker */ |
934 | 936 |
if (!is_arj_archive(fd)) { |
935 | 937 |
cli_dbgmsg("Not in ARJ format\n"); |
... | ... |
@@ -945,6 +946,9 @@ int cli_unarj_extract_file(int fd, const char *dirname, arj_metadata_t *metadata |
945 | 945 |
char filename[1024]; |
946 | 946 |
|
947 | 947 |
cli_dbgmsg("in cli_unarj_extract_file\n"); |
948 |
+ if (!metadata || !dirname || (fd < 0)) { |
|
949 |
+ return CL_ENULLARG; |
|
950 |
+ } |
|
948 | 951 |
|
949 | 952 |
if (metadata->encrypted) { |
950 | 953 |
cli_dbgmsg("PASSWORDed file (skipping)\n"); |
... | ... |
@@ -985,4 +989,3 @@ int cli_unarj_extract_file(int fd, const char *dirname, arj_metadata_t *metadata |
985 | 985 |
} |
986 | 986 |
return ret; |
987 | 987 |
} |
988 |
- |
... | ... |
@@ -22,15 +22,10 @@ |
22 | 22 |
#define __UNARJ_H |
23 | 23 |
|
24 | 24 |
typedef struct arj_metadata_tag { |
25 |
- uint8_t min_version; |
|
26 | 25 |
uint32_t comp_size; |
27 | 26 |
uint32_t orig_size; |
28 |
- uint32_t orig_crc; |
|
29 |
- uint8_t host_os; |
|
30 |
- uint8_t flags; |
|
31 | 27 |
uint8_t method; |
32 | 28 |
char *filename; |
33 |
- uint32_t crc; |
|
34 | 29 |
int encrypted; |
35 | 30 |
int ofd; |
36 | 31 |
} arj_metadata_t; |