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
This commit is contained in:
parent
0102a9fd48
commit
1b1cfde1f8
@ -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>
|
||||
@ -57,12 +58,13 @@
|
||||
#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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
37
tar.c
37
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>
|
||||
@ -57,12 +58,13 @@
|
||||
#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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user