Fix bug#1043 -- hanlde long filenames and links (in this case, by complaining
authorEric Andersen <andersen@codepoet.org>
Sun, 24 Sep 2000 00:54:37 +0000 (00:54 -0000)
committerEric Andersen <andersen@codepoet.org>
Sun, 24 Sep 2000 00:54:37 +0000 (00:54 -0000)
that thay exist and skipping such files when extracting and when archiving.
 -Erik

archival/tar.c
messages.c
tar.c

index 6dcda53ef222f775b256b419d79562a354015d2d..e4bdd0a6c092a5e8fe5eaf638d915b9060a2e443 100644 (file)
@@ -39,6 +39,7 @@
 #include "internal.h"
 #define BB_DECLARE_EXTERN
 #define bb_need_io_error
+#define bb_need_name_longer_then_foo
 #include "messages.c"
 #include <stdio.h>
 #include <dirent.h>
 #define MINOR(dev) ((dev)&0xff)
 #endif
 
+#define NAME_SIZE      100
 
 /* POSIX tar Header Block, from POSIX 1003.1-1990  */
 struct TarHeader
 {
                                 /* byte offset */
-       char name[100];               /*   0-99 */
+       char name[NAME_SIZE];         /*   0-99 */
        char mode[8];                 /* 100-107 */
        char uid[8];                  /* 108-115 */
        char gid[8];                  /* 116-123 */
@@ -70,7 +72,7 @@ struct TarHeader
        char mtime[12];               /* 136-147 */
        char chksum[8];               /* 148-155 */
        char typeflag;                /* 156-156 */
-       char linkname[100];           /* 157-256 */
+       char linkname[NAME_SIZE];     /* 157-256 */
        char magic[6];                /* 257-262 */
        char version[2];              /* 263-264 */
        char uname[32];               /* 265-296 */
@@ -102,6 +104,8 @@ enum TarFileType
        DIRTYPE  = '5',            /* directory */
        FIFOTYPE = '6',            /* FIFO special */
        CONTTYPE = '7',            /* reserved */
+       GNULONGLINK = 'K',         /* GNU long (>100 chars) link name */
+       GNULONGNAME = 'L',         /* GNU long (>100 chars) file name */
 };
 typedef enum TarFileType TarFileType;
 
@@ -496,6 +500,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
 {
        int status, tarFd=-1;
        int errorFlag=FALSE;
+       int skipNextHeaderFlag=FALSE;
        TarHeader rawHeader;
        TarInfo header;
        char** tmpList;
@@ -517,7 +522,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
        /* Read the tar file, and iterate over it one file at a time */
        while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) {
 
-               /* First, try to read the header */
+               /* Try to read the header */
                if ( readTarHeader(&rawHeader, &header) == FALSE ) {
                        if ( *(header.name) == '\0' ) {
                                goto endgame;
@@ -531,6 +536,19 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
                                goto endgame;
                header.tarFd = tarFd;
 
+               /* Skip funky extra GNU headers that precede long files */
+               if ( (header.type == GNULONGNAME) || (header.type == GNULONGLINK) ) {
+                       skipNextHeaderFlag=TRUE;
+                       tarExtractRegularFile(&header, FALSE, FALSE);
+                       continue;
+               }
+               if ( skipNextHeaderFlag == TRUE ) { 
+                       skipNextHeaderFlag=FALSE;
+                       errorMsg(name_longer_then_foo, NAME_SIZE); 
+                       tarExtractRegularFile(&header, FALSE, FALSE);
+                       continue;
+               }
+
 #if defined BB_FEATURE_TAR_EXCLUDE
                {
                        int skipFlag=FALSE;
@@ -671,7 +689,15 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
                                if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE)
                                        errorFlag=TRUE;
                                break;
+#if 0
+                       /* Handled earlier */
+                       case GNULONGNAME:
+                       case GNULONGLINK:
+                               skipNextHeaderFlag=TRUE;
+                               break;
+#endif
                        default:
+                               errorMsg("Unknown file type '%c' in tar file\n", header.type);
                                close( tarFd);
                                return( FALSE);
                }
@@ -897,6 +923,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
                return( TRUE);
        }
 
+       if (strlen(fileName) >= NAME_SIZE) {
+               errorMsg(name_longer_then_foo, NAME_SIZE);
+               return ( TRUE);
+       }
+
        if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) {
                return( FALSE);
        } 
index 34b39f258e7eb247cfcdd96cb494a73a18c0435f..f7a772cbd8a96fadf88c1b42fdfefc9f6718639e 100644 (file)
@@ -81,9 +81,9 @@
 #if defined bb_need_too_few_args || ! defined BB_DECLARE_EXTERN
        BB_DEF_MESSAGE(too_few_args, "too few arguments\n")
 #endif
-
-
-
+#if defined bb_need_name_longer_then_foo || ! defined BB_DECLARE_EXTERN
+       BB_DEF_MESSAGE(name_longer_then_foo, "Names longer then %d chars not supported.\n")
+#endif
 
 
 #endif /* _BB_MESSAGES_C */
diff --git a/tar.c b/tar.c
index 6dcda53ef222f775b256b419d79562a354015d2d..e4bdd0a6c092a5e8fe5eaf638d915b9060a2e443 100644 (file)
--- a/tar.c
+++ b/tar.c
@@ -39,6 +39,7 @@
 #include "internal.h"
 #define BB_DECLARE_EXTERN
 #define bb_need_io_error
+#define bb_need_name_longer_then_foo
 #include "messages.c"
 #include <stdio.h>
 #include <dirent.h>
 #define MINOR(dev) ((dev)&0xff)
 #endif
 
+#define NAME_SIZE      100
 
 /* POSIX tar Header Block, from POSIX 1003.1-1990  */
 struct TarHeader
 {
                                 /* byte offset */
-       char name[100];               /*   0-99 */
+       char name[NAME_SIZE];         /*   0-99 */
        char mode[8];                 /* 100-107 */
        char uid[8];                  /* 108-115 */
        char gid[8];                  /* 116-123 */
@@ -70,7 +72,7 @@ struct TarHeader
        char mtime[12];               /* 136-147 */
        char chksum[8];               /* 148-155 */
        char typeflag;                /* 156-156 */
-       char linkname[100];           /* 157-256 */
+       char linkname[NAME_SIZE];     /* 157-256 */
        char magic[6];                /* 257-262 */
        char version[2];              /* 263-264 */
        char uname[32];               /* 265-296 */
@@ -102,6 +104,8 @@ enum TarFileType
        DIRTYPE  = '5',            /* directory */
        FIFOTYPE = '6',            /* FIFO special */
        CONTTYPE = '7',            /* reserved */
+       GNULONGLINK = 'K',         /* GNU long (>100 chars) link name */
+       GNULONGNAME = 'L',         /* GNU long (>100 chars) file name */
 };
 typedef enum TarFileType TarFileType;
 
@@ -496,6 +500,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
 {
        int status, tarFd=-1;
        int errorFlag=FALSE;
+       int skipNextHeaderFlag=FALSE;
        TarHeader rawHeader;
        TarInfo header;
        char** tmpList;
@@ -517,7 +522,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
        /* Read the tar file, and iterate over it one file at a time */
        while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) {
 
-               /* First, try to read the header */
+               /* Try to read the header */
                if ( readTarHeader(&rawHeader, &header) == FALSE ) {
                        if ( *(header.name) == '\0' ) {
                                goto endgame;
@@ -531,6 +536,19 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
                                goto endgame;
                header.tarFd = tarFd;
 
+               /* Skip funky extra GNU headers that precede long files */
+               if ( (header.type == GNULONGNAME) || (header.type == GNULONGLINK) ) {
+                       skipNextHeaderFlag=TRUE;
+                       tarExtractRegularFile(&header, FALSE, FALSE);
+                       continue;
+               }
+               if ( skipNextHeaderFlag == TRUE ) { 
+                       skipNextHeaderFlag=FALSE;
+                       errorMsg(name_longer_then_foo, NAME_SIZE); 
+                       tarExtractRegularFile(&header, FALSE, FALSE);
+                       continue;
+               }
+
 #if defined BB_FEATURE_TAR_EXCLUDE
                {
                        int skipFlag=FALSE;
@@ -671,7 +689,15 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
                                if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE)
                                        errorFlag=TRUE;
                                break;
+#if 0
+                       /* Handled earlier */
+                       case GNULONGNAME:
+                       case GNULONGLINK:
+                               skipNextHeaderFlag=TRUE;
+                               break;
+#endif
                        default:
+                               errorMsg("Unknown file type '%c' in tar file\n", header.type);
                                close( tarFd);
                                return( FALSE);
                }
@@ -897,6 +923,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
                return( TRUE);
        }
 
+       if (strlen(fileName) >= NAME_SIZE) {
+               errorMsg(name_longer_then_foo, NAME_SIZE);
+               return ( TRUE);
+       }
+
        if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) {
                return( FALSE);
        }