aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2000-09-24 00:54:37 +0000
committerEric Andersen <andersen@codepoet.org>2000-09-24 00:54:37 +0000
commit1b1cfde1f8d66eafb1faa1b3272f9dac4c3b5b5b (patch)
tree759e50cf4fdc135f0e9498d7e609601ea102e8cd
parent0102a9fd48fe9ed16a1e2ad372cfa0fb65e87208 (diff)
downloadbusybox-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.c37
-rw-r--r--messages.c6
-rw-r--r--tar.c37
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 */
62struct TarHeader 64struct 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};
106typedef enum TarFileType TarFileType; 110typedef 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 */
diff --git a/tar.c b/tar.c
index 6dcda53ef..e4bdd0a6c 100644
--- a/tar.c
+++ b/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 */
62struct TarHeader 64struct 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};
106typedef enum TarFileType TarFileType; 110typedef 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 }