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"
|
#include "internal.h"
|
||||||
#define BB_DECLARE_EXTERN
|
#define BB_DECLARE_EXTERN
|
||||||
#define bb_need_io_error
|
#define bb_need_io_error
|
||||||
|
#define bb_need_name_longer_then_foo
|
||||||
#include "messages.c"
|
#include "messages.c"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
@ -57,12 +58,13 @@
|
|||||||
#define MINOR(dev) ((dev)&0xff)
|
#define MINOR(dev) ((dev)&0xff)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define NAME_SIZE 100
|
||||||
|
|
||||||
/* POSIX tar Header Block, from POSIX 1003.1-1990 */
|
/* POSIX tar Header Block, from POSIX 1003.1-1990 */
|
||||||
struct TarHeader
|
struct TarHeader
|
||||||
{
|
{
|
||||||
/* byte offset */
|
/* byte offset */
|
||||||
char name[100]; /* 0-99 */
|
char name[NAME_SIZE]; /* 0-99 */
|
||||||
char mode[8]; /* 100-107 */
|
char mode[8]; /* 100-107 */
|
||||||
char uid[8]; /* 108-115 */
|
char uid[8]; /* 108-115 */
|
||||||
char gid[8]; /* 116-123 */
|
char gid[8]; /* 116-123 */
|
||||||
@ -70,7 +72,7 @@ struct TarHeader
|
|||||||
char mtime[12]; /* 136-147 */
|
char mtime[12]; /* 136-147 */
|
||||||
char chksum[8]; /* 148-155 */
|
char chksum[8]; /* 148-155 */
|
||||||
char typeflag; /* 156-156 */
|
char typeflag; /* 156-156 */
|
||||||
char linkname[100]; /* 157-256 */
|
char linkname[NAME_SIZE]; /* 157-256 */
|
||||||
char magic[6]; /* 257-262 */
|
char magic[6]; /* 257-262 */
|
||||||
char version[2]; /* 263-264 */
|
char version[2]; /* 263-264 */
|
||||||
char uname[32]; /* 265-296 */
|
char uname[32]; /* 265-296 */
|
||||||
@ -102,6 +104,8 @@ enum TarFileType
|
|||||||
DIRTYPE = '5', /* directory */
|
DIRTYPE = '5', /* directory */
|
||||||
FIFOTYPE = '6', /* FIFO special */
|
FIFOTYPE = '6', /* FIFO special */
|
||||||
CONTTYPE = '7', /* reserved */
|
CONTTYPE = '7', /* reserved */
|
||||||
|
GNULONGLINK = 'K', /* GNU long (>100 chars) link name */
|
||||||
|
GNULONGNAME = 'L', /* GNU long (>100 chars) file name */
|
||||||
};
|
};
|
||||||
typedef enum TarFileType TarFileType;
|
typedef enum TarFileType TarFileType;
|
||||||
|
|
||||||
@ -496,6 +500,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
|
|||||||
{
|
{
|
||||||
int status, tarFd=-1;
|
int status, tarFd=-1;
|
||||||
int errorFlag=FALSE;
|
int errorFlag=FALSE;
|
||||||
|
int skipNextHeaderFlag=FALSE;
|
||||||
TarHeader rawHeader;
|
TarHeader rawHeader;
|
||||||
TarInfo header;
|
TarInfo header;
|
||||||
char** tmpList;
|
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 */
|
/* 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 ) {
|
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 ( readTarHeader(&rawHeader, &header) == FALSE ) {
|
||||||
if ( *(header.name) == '\0' ) {
|
if ( *(header.name) == '\0' ) {
|
||||||
goto endgame;
|
goto endgame;
|
||||||
@ -531,6 +536,19 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
|
|||||||
goto endgame;
|
goto endgame;
|
||||||
header.tarFd = tarFd;
|
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
|
#if defined BB_FEATURE_TAR_EXCLUDE
|
||||||
{
|
{
|
||||||
int skipFlag=FALSE;
|
int skipFlag=FALSE;
|
||||||
@ -671,7 +689,15 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
|
|||||||
if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE)
|
if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE)
|
||||||
errorFlag=TRUE;
|
errorFlag=TRUE;
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
|
/* Handled earlier */
|
||||||
|
case GNULONGNAME:
|
||||||
|
case GNULONGLINK:
|
||||||
|
skipNextHeaderFlag=TRUE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
|
errorMsg("Unknown file type '%c' in tar file\n", header.type);
|
||||||
close( tarFd);
|
close( tarFd);
|
||||||
return( FALSE);
|
return( FALSE);
|
||||||
}
|
}
|
||||||
@ -897,6 +923,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
|
|||||||
return( TRUE);
|
return( TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen(fileName) >= NAME_SIZE) {
|
||||||
|
errorMsg(name_longer_then_foo, NAME_SIZE);
|
||||||
|
return ( TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) {
|
if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) {
|
||||||
return( FALSE);
|
return( FALSE);
|
||||||
}
|
}
|
||||||
|
@ -81,9 +81,9 @@
|
|||||||
#if defined bb_need_too_few_args || ! defined BB_DECLARE_EXTERN
|
#if defined bb_need_too_few_args || ! defined BB_DECLARE_EXTERN
|
||||||
BB_DEF_MESSAGE(too_few_args, "too few arguments\n")
|
BB_DEF_MESSAGE(too_few_args, "too few arguments\n")
|
||||||
#endif
|
#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 */
|
#endif /* _BB_MESSAGES_C */
|
||||||
|
37
tar.c
37
tar.c
@ -39,6 +39,7 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#define BB_DECLARE_EXTERN
|
#define BB_DECLARE_EXTERN
|
||||||
#define bb_need_io_error
|
#define bb_need_io_error
|
||||||
|
#define bb_need_name_longer_then_foo
|
||||||
#include "messages.c"
|
#include "messages.c"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
@ -57,12 +58,13 @@
|
|||||||
#define MINOR(dev) ((dev)&0xff)
|
#define MINOR(dev) ((dev)&0xff)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define NAME_SIZE 100
|
||||||
|
|
||||||
/* POSIX tar Header Block, from POSIX 1003.1-1990 */
|
/* POSIX tar Header Block, from POSIX 1003.1-1990 */
|
||||||
struct TarHeader
|
struct TarHeader
|
||||||
{
|
{
|
||||||
/* byte offset */
|
/* byte offset */
|
||||||
char name[100]; /* 0-99 */
|
char name[NAME_SIZE]; /* 0-99 */
|
||||||
char mode[8]; /* 100-107 */
|
char mode[8]; /* 100-107 */
|
||||||
char uid[8]; /* 108-115 */
|
char uid[8]; /* 108-115 */
|
||||||
char gid[8]; /* 116-123 */
|
char gid[8]; /* 116-123 */
|
||||||
@ -70,7 +72,7 @@ struct TarHeader
|
|||||||
char mtime[12]; /* 136-147 */
|
char mtime[12]; /* 136-147 */
|
||||||
char chksum[8]; /* 148-155 */
|
char chksum[8]; /* 148-155 */
|
||||||
char typeflag; /* 156-156 */
|
char typeflag; /* 156-156 */
|
||||||
char linkname[100]; /* 157-256 */
|
char linkname[NAME_SIZE]; /* 157-256 */
|
||||||
char magic[6]; /* 257-262 */
|
char magic[6]; /* 257-262 */
|
||||||
char version[2]; /* 263-264 */
|
char version[2]; /* 263-264 */
|
||||||
char uname[32]; /* 265-296 */
|
char uname[32]; /* 265-296 */
|
||||||
@ -102,6 +104,8 @@ enum TarFileType
|
|||||||
DIRTYPE = '5', /* directory */
|
DIRTYPE = '5', /* directory */
|
||||||
FIFOTYPE = '6', /* FIFO special */
|
FIFOTYPE = '6', /* FIFO special */
|
||||||
CONTTYPE = '7', /* reserved */
|
CONTTYPE = '7', /* reserved */
|
||||||
|
GNULONGLINK = 'K', /* GNU long (>100 chars) link name */
|
||||||
|
GNULONGNAME = 'L', /* GNU long (>100 chars) file name */
|
||||||
};
|
};
|
||||||
typedef enum TarFileType TarFileType;
|
typedef enum TarFileType TarFileType;
|
||||||
|
|
||||||
@ -496,6 +500,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
|
|||||||
{
|
{
|
||||||
int status, tarFd=-1;
|
int status, tarFd=-1;
|
||||||
int errorFlag=FALSE;
|
int errorFlag=FALSE;
|
||||||
|
int skipNextHeaderFlag=FALSE;
|
||||||
TarHeader rawHeader;
|
TarHeader rawHeader;
|
||||||
TarInfo header;
|
TarInfo header;
|
||||||
char** tmpList;
|
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 */
|
/* 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 ) {
|
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 ( readTarHeader(&rawHeader, &header) == FALSE ) {
|
||||||
if ( *(header.name) == '\0' ) {
|
if ( *(header.name) == '\0' ) {
|
||||||
goto endgame;
|
goto endgame;
|
||||||
@ -531,6 +536,19 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
|
|||||||
goto endgame;
|
goto endgame;
|
||||||
header.tarFd = tarFd;
|
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
|
#if defined BB_FEATURE_TAR_EXCLUDE
|
||||||
{
|
{
|
||||||
int skipFlag=FALSE;
|
int skipFlag=FALSE;
|
||||||
@ -671,7 +689,15 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
|
|||||||
if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE)
|
if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE)
|
||||||
errorFlag=TRUE;
|
errorFlag=TRUE;
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
|
/* Handled earlier */
|
||||||
|
case GNULONGNAME:
|
||||||
|
case GNULONGLINK:
|
||||||
|
skipNextHeaderFlag=TRUE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
|
errorMsg("Unknown file type '%c' in tar file\n", header.type);
|
||||||
close( tarFd);
|
close( tarFd);
|
||||||
return( FALSE);
|
return( FALSE);
|
||||||
}
|
}
|
||||||
@ -897,6 +923,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
|
|||||||
return( TRUE);
|
return( TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen(fileName) >= NAME_SIZE) {
|
||||||
|
errorMsg(name_longer_then_foo, NAME_SIZE);
|
||||||
|
return ( TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) {
|
if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) {
|
||||||
return( FALSE);
|
return( FALSE);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user