diff options
author | Eric Andersen <andersen@codepoet.org> | 2000-09-24 00:54:37 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2000-09-24 00:54:37 +0000 |
commit | 1b1cfde1f8d66eafb1faa1b3272f9dac4c3b5b5b (patch) | |
tree | 759e50cf4fdc135f0e9498d7e609601ea102e8cd | |
parent | 0102a9fd48fe9ed16a1e2ad372cfa0fb65e87208 (diff) | |
download | busybox-w32-1b1cfde1f8d66eafb1faa1b3272f9dac4c3b5b5b.tar.gz busybox-w32-1b1cfde1f8d66eafb1faa1b3272f9dac4c3b5b5b.tar.bz2 busybox-w32-1b1cfde1f8d66eafb1faa1b3272f9dac4c3b5b5b.zip |
Fix bug#1043 -- hanlde long filenames and links (in this case, by complaining
that thay exist and skipping such files when extracting and when archiving.
-Erik
-rw-r--r-- | archival/tar.c | 37 | ||||
-rw-r--r-- | messages.c | 6 | ||||
-rw-r--r-- | tar.c | 37 |
3 files changed, 71 insertions, 9 deletions
diff --git a/archival/tar.c b/archival/tar.c index 6dcda53ef..e4bdd0a6c 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "internal.h" | 39 | #include "internal.h" |
40 | #define BB_DECLARE_EXTERN | 40 | #define BB_DECLARE_EXTERN |
41 | #define bb_need_io_error | 41 | #define bb_need_io_error |
42 | #define bb_need_name_longer_then_foo | ||
42 | #include "messages.c" | 43 | #include "messages.c" |
43 | #include <stdio.h> | 44 | #include <stdio.h> |
44 | #include <dirent.h> | 45 | #include <dirent.h> |
@@ -57,12 +58,13 @@ | |||
57 | #define MINOR(dev) ((dev)&0xff) | 58 | #define MINOR(dev) ((dev)&0xff) |
58 | #endif | 59 | #endif |
59 | 60 | ||
61 | #define NAME_SIZE 100 | ||
60 | 62 | ||
61 | /* POSIX tar Header Block, from POSIX 1003.1-1990 */ | 63 | /* POSIX tar Header Block, from POSIX 1003.1-1990 */ |
62 | struct TarHeader | 64 | struct TarHeader |
63 | { | 65 | { |
64 | /* byte offset */ | 66 | /* byte offset */ |
65 | char name[100]; /* 0-99 */ | 67 | char name[NAME_SIZE]; /* 0-99 */ |
66 | char mode[8]; /* 100-107 */ | 68 | char mode[8]; /* 100-107 */ |
67 | char uid[8]; /* 108-115 */ | 69 | char uid[8]; /* 108-115 */ |
68 | char gid[8]; /* 116-123 */ | 70 | char gid[8]; /* 116-123 */ |
@@ -70,7 +72,7 @@ struct TarHeader | |||
70 | char mtime[12]; /* 136-147 */ | 72 | char mtime[12]; /* 136-147 */ |
71 | char chksum[8]; /* 148-155 */ | 73 | char chksum[8]; /* 148-155 */ |
72 | char typeflag; /* 156-156 */ | 74 | char typeflag; /* 156-156 */ |
73 | char linkname[100]; /* 157-256 */ | 75 | char linkname[NAME_SIZE]; /* 157-256 */ |
74 | char magic[6]; /* 257-262 */ | 76 | char magic[6]; /* 257-262 */ |
75 | char version[2]; /* 263-264 */ | 77 | char version[2]; /* 263-264 */ |
76 | char uname[32]; /* 265-296 */ | 78 | char uname[32]; /* 265-296 */ |
@@ -102,6 +104,8 @@ enum TarFileType | |||
102 | DIRTYPE = '5', /* directory */ | 104 | DIRTYPE = '5', /* directory */ |
103 | FIFOTYPE = '6', /* FIFO special */ | 105 | FIFOTYPE = '6', /* FIFO special */ |
104 | CONTTYPE = '7', /* reserved */ | 106 | CONTTYPE = '7', /* reserved */ |
107 | GNULONGLINK = 'K', /* GNU long (>100 chars) link name */ | ||
108 | GNULONGNAME = 'L', /* GNU long (>100 chars) file name */ | ||
105 | }; | 109 | }; |
106 | typedef enum TarFileType TarFileType; | 110 | typedef enum TarFileType TarFileType; |
107 | 111 | ||
@@ -496,6 +500,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, | |||
496 | { | 500 | { |
497 | int status, tarFd=-1; | 501 | int status, tarFd=-1; |
498 | int errorFlag=FALSE; | 502 | int errorFlag=FALSE; |
503 | int skipNextHeaderFlag=FALSE; | ||
499 | TarHeader rawHeader; | 504 | TarHeader rawHeader; |
500 | TarInfo header; | 505 | TarInfo header; |
501 | char** tmpList; | 506 | char** tmpList; |
@@ -517,7 +522,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, | |||
517 | /* Read the tar file, and iterate over it one file at a time */ | 522 | /* Read the tar file, and iterate over it one file at a time */ |
518 | while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) { | 523 | while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) { |
519 | 524 | ||
520 | /* First, try to read the header */ | 525 | /* Try to read the header */ |
521 | if ( readTarHeader(&rawHeader, &header) == FALSE ) { | 526 | if ( readTarHeader(&rawHeader, &header) == FALSE ) { |
522 | if ( *(header.name) == '\0' ) { | 527 | if ( *(header.name) == '\0' ) { |
523 | goto endgame; | 528 | goto endgame; |
@@ -531,6 +536,19 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, | |||
531 | goto endgame; | 536 | goto endgame; |
532 | header.tarFd = tarFd; | 537 | header.tarFd = tarFd; |
533 | 538 | ||
539 | /* Skip funky extra GNU headers that precede long files */ | ||
540 | if ( (header.type == GNULONGNAME) || (header.type == GNULONGLINK) ) { | ||
541 | skipNextHeaderFlag=TRUE; | ||
542 | tarExtractRegularFile(&header, FALSE, FALSE); | ||
543 | continue; | ||
544 | } | ||
545 | if ( skipNextHeaderFlag == TRUE ) { | ||
546 | skipNextHeaderFlag=FALSE; | ||
547 | errorMsg(name_longer_then_foo, NAME_SIZE); | ||
548 | tarExtractRegularFile(&header, FALSE, FALSE); | ||
549 | continue; | ||
550 | } | ||
551 | |||
534 | #if defined BB_FEATURE_TAR_EXCLUDE | 552 | #if defined BB_FEATURE_TAR_EXCLUDE |
535 | { | 553 | { |
536 | int skipFlag=FALSE; | 554 | int skipFlag=FALSE; |
@@ -671,7 +689,15 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, | |||
671 | if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE) | 689 | if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE) |
672 | errorFlag=TRUE; | 690 | errorFlag=TRUE; |
673 | break; | 691 | break; |
692 | #if 0 | ||
693 | /* Handled earlier */ | ||
694 | case GNULONGNAME: | ||
695 | case GNULONGLINK: | ||
696 | skipNextHeaderFlag=TRUE; | ||
697 | break; | ||
698 | #endif | ||
674 | default: | 699 | default: |
700 | errorMsg("Unknown file type '%c' in tar file\n", header.type); | ||
675 | close( tarFd); | 701 | close( tarFd); |
676 | return( FALSE); | 702 | return( FALSE); |
677 | } | 703 | } |
@@ -897,6 +923,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* | |||
897 | return( TRUE); | 923 | return( TRUE); |
898 | } | 924 | } |
899 | 925 | ||
926 | if (strlen(fileName) >= NAME_SIZE) { | ||
927 | errorMsg(name_longer_then_foo, NAME_SIZE); | ||
928 | return ( TRUE); | ||
929 | } | ||
930 | |||
900 | if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) { | 931 | if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) { |
901 | return( FALSE); | 932 | return( FALSE); |
902 | } | 933 | } |
diff --git a/messages.c b/messages.c index 34b39f258..f7a772cbd 100644 --- a/messages.c +++ b/messages.c | |||
@@ -81,9 +81,9 @@ | |||
81 | #if defined bb_need_too_few_args || ! defined BB_DECLARE_EXTERN | 81 | #if defined bb_need_too_few_args || ! defined BB_DECLARE_EXTERN |
82 | BB_DEF_MESSAGE(too_few_args, "too few arguments\n") | 82 | BB_DEF_MESSAGE(too_few_args, "too few arguments\n") |
83 | #endif | 83 | #endif |
84 | 84 | #if defined bb_need_name_longer_then_foo || ! defined BB_DECLARE_EXTERN | |
85 | 85 | BB_DEF_MESSAGE(name_longer_then_foo, "Names longer then %d chars not supported.\n") | |
86 | 86 | #endif | |
87 | 87 | ||
88 | 88 | ||
89 | #endif /* _BB_MESSAGES_C */ | 89 | #endif /* _BB_MESSAGES_C */ |
@@ -39,6 +39,7 @@ | |||
39 | #include "internal.h" | 39 | #include "internal.h" |
40 | #define BB_DECLARE_EXTERN | 40 | #define BB_DECLARE_EXTERN |
41 | #define bb_need_io_error | 41 | #define bb_need_io_error |
42 | #define bb_need_name_longer_then_foo | ||
42 | #include "messages.c" | 43 | #include "messages.c" |
43 | #include <stdio.h> | 44 | #include <stdio.h> |
44 | #include <dirent.h> | 45 | #include <dirent.h> |
@@ -57,12 +58,13 @@ | |||
57 | #define MINOR(dev) ((dev)&0xff) | 58 | #define MINOR(dev) ((dev)&0xff) |
58 | #endif | 59 | #endif |
59 | 60 | ||
61 | #define NAME_SIZE 100 | ||
60 | 62 | ||
61 | /* POSIX tar Header Block, from POSIX 1003.1-1990 */ | 63 | /* POSIX tar Header Block, from POSIX 1003.1-1990 */ |
62 | struct TarHeader | 64 | struct TarHeader |
63 | { | 65 | { |
64 | /* byte offset */ | 66 | /* byte offset */ |
65 | char name[100]; /* 0-99 */ | 67 | char name[NAME_SIZE]; /* 0-99 */ |
66 | char mode[8]; /* 100-107 */ | 68 | char mode[8]; /* 100-107 */ |
67 | char uid[8]; /* 108-115 */ | 69 | char uid[8]; /* 108-115 */ |
68 | char gid[8]; /* 116-123 */ | 70 | char gid[8]; /* 116-123 */ |
@@ -70,7 +72,7 @@ struct TarHeader | |||
70 | char mtime[12]; /* 136-147 */ | 72 | char mtime[12]; /* 136-147 */ |
71 | char chksum[8]; /* 148-155 */ | 73 | char chksum[8]; /* 148-155 */ |
72 | char typeflag; /* 156-156 */ | 74 | char typeflag; /* 156-156 */ |
73 | char linkname[100]; /* 157-256 */ | 75 | char linkname[NAME_SIZE]; /* 157-256 */ |
74 | char magic[6]; /* 257-262 */ | 76 | char magic[6]; /* 257-262 */ |
75 | char version[2]; /* 263-264 */ | 77 | char version[2]; /* 263-264 */ |
76 | char uname[32]; /* 265-296 */ | 78 | char uname[32]; /* 265-296 */ |
@@ -102,6 +104,8 @@ enum TarFileType | |||
102 | DIRTYPE = '5', /* directory */ | 104 | DIRTYPE = '5', /* directory */ |
103 | FIFOTYPE = '6', /* FIFO special */ | 105 | FIFOTYPE = '6', /* FIFO special */ |
104 | CONTTYPE = '7', /* reserved */ | 106 | CONTTYPE = '7', /* reserved */ |
107 | GNULONGLINK = 'K', /* GNU long (>100 chars) link name */ | ||
108 | GNULONGNAME = 'L', /* GNU long (>100 chars) file name */ | ||
105 | }; | 109 | }; |
106 | typedef enum TarFileType TarFileType; | 110 | typedef enum TarFileType TarFileType; |
107 | 111 | ||
@@ -496,6 +500,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, | |||
496 | { | 500 | { |
497 | int status, tarFd=-1; | 501 | int status, tarFd=-1; |
498 | int errorFlag=FALSE; | 502 | int errorFlag=FALSE; |
503 | int skipNextHeaderFlag=FALSE; | ||
499 | TarHeader rawHeader; | 504 | TarHeader rawHeader; |
500 | TarInfo header; | 505 | TarInfo header; |
501 | char** tmpList; | 506 | char** tmpList; |
@@ -517,7 +522,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, | |||
517 | /* Read the tar file, and iterate over it one file at a time */ | 522 | /* Read the tar file, and iterate over it one file at a time */ |
518 | while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) { | 523 | while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) { |
519 | 524 | ||
520 | /* First, try to read the header */ | 525 | /* Try to read the header */ |
521 | if ( readTarHeader(&rawHeader, &header) == FALSE ) { | 526 | if ( readTarHeader(&rawHeader, &header) == FALSE ) { |
522 | if ( *(header.name) == '\0' ) { | 527 | if ( *(header.name) == '\0' ) { |
523 | goto endgame; | 528 | goto endgame; |
@@ -531,6 +536,19 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, | |||
531 | goto endgame; | 536 | goto endgame; |
532 | header.tarFd = tarFd; | 537 | header.tarFd = tarFd; |
533 | 538 | ||
539 | /* Skip funky extra GNU headers that precede long files */ | ||
540 | if ( (header.type == GNULONGNAME) || (header.type == GNULONGLINK) ) { | ||
541 | skipNextHeaderFlag=TRUE; | ||
542 | tarExtractRegularFile(&header, FALSE, FALSE); | ||
543 | continue; | ||
544 | } | ||
545 | if ( skipNextHeaderFlag == TRUE ) { | ||
546 | skipNextHeaderFlag=FALSE; | ||
547 | errorMsg(name_longer_then_foo, NAME_SIZE); | ||
548 | tarExtractRegularFile(&header, FALSE, FALSE); | ||
549 | continue; | ||
550 | } | ||
551 | |||
534 | #if defined BB_FEATURE_TAR_EXCLUDE | 552 | #if defined BB_FEATURE_TAR_EXCLUDE |
535 | { | 553 | { |
536 | int skipFlag=FALSE; | 554 | int skipFlag=FALSE; |
@@ -671,7 +689,15 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, | |||
671 | if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE) | 689 | if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE) |
672 | errorFlag=TRUE; | 690 | errorFlag=TRUE; |
673 | break; | 691 | break; |
692 | #if 0 | ||
693 | /* Handled earlier */ | ||
694 | case GNULONGNAME: | ||
695 | case GNULONGLINK: | ||
696 | skipNextHeaderFlag=TRUE; | ||
697 | break; | ||
698 | #endif | ||
674 | default: | 699 | default: |
700 | errorMsg("Unknown file type '%c' in tar file\n", header.type); | ||
675 | close( tarFd); | 701 | close( tarFd); |
676 | return( FALSE); | 702 | return( FALSE); |
677 | } | 703 | } |
@@ -897,6 +923,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* | |||
897 | return( TRUE); | 923 | return( TRUE); |
898 | } | 924 | } |
899 | 925 | ||
926 | if (strlen(fileName) >= NAME_SIZE) { | ||
927 | errorMsg(name_longer_then_foo, NAME_SIZE); | ||
928 | return ( TRUE); | ||
929 | } | ||
930 | |||
900 | if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) { | 931 | if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) { |
901 | return( FALSE); | 932 | return( FALSE); |
902 | } | 933 | } |