From 2e41d0cb777e6af086b45555551780e02ad13f46 Mon Sep 17 00:00:00 2001 From: Glenn L McGrath Date: Fri, 27 Sep 2002 06:46:02 +0000 Subject: Fix compress support and prevent a segfault --- archival/gunzip.c | 22 ++++++++++++++++++---- archival/libunarchive/check_header_gzip.c | 11 ++--------- archival/libunarchive/data_extract_all.c | 1 - archival/libunarchive/decompress_uncompress.c | 26 ++++++++++---------------- archival/libunarchive/filter_accept_all.c | 6 +++++- archival/libunarchive/get_header_tar.c | 1 - archival/libunarchive/get_header_tar_gz.c | 9 ++++++++- archival/libunarchive/uncompress.c | 26 ++++++++++---------------- archival/rpm2cpio.c | 6 ++++++ include/libbb.h | 1 + include/unarchive.h | 2 +- libbb/uncompress.c | 26 ++++++++++---------------- 12 files changed, 71 insertions(+), 66 deletions(-) diff --git a/archival/gunzip.c b/archival/gunzip.c index 4489204fb..6ec5c69ae 100644 --- a/archival/gunzip.c +++ b/archival/gunzip.c @@ -163,11 +163,25 @@ extern int gunzip_main(int argc, char **argv) } /* do the decompression, and cleanup */ - check_header_gzip(src_fd); - if (inflate(src_fd, dst_fd) != 0) { - error_msg("Error inflating"); + if (xread_char(src_fd) == 0x1f) { + unsigned char magic2; + + magic2 = xread_char(src_fd); +#ifdef CONFIG_FEATURE_UNCOMPRESS + if (magic2 == 0x9d) { + return(uncompress(src_fd, dst_fd)); + } else +#endif + if (magic2 == 0x8b) { + check_header_gzip(src_fd); + if (inflate(src_fd, dst_fd) != 0) { + error_msg("Error inflating"); + } + check_trailer_gzip(src_fd); + } else { + error_msg_and_die("Invalid magic\n"); + } } - check_trailer_gzip(src_fd); if ((status != EXIT_SUCCESS) && (new_path)) { /* Unzip failed, remove new path instead of old path */ diff --git a/archival/libunarchive/check_header_gzip.c b/archival/libunarchive/check_header_gzip.c index 508d30924..e8bb8d547 100644 --- a/archival/libunarchive/check_header_gzip.c +++ b/archival/libunarchive/check_header_gzip.c @@ -5,9 +5,8 @@ extern void check_header_gzip(int src_fd) { union { - unsigned char raw[10]; + unsigned char raw[8]; struct { - unsigned char magic[2]; unsigned char method; unsigned char flags; unsigned int mtime; @@ -16,13 +15,7 @@ extern void check_header_gzip(int src_fd) } formated; } header; - xread_all(src_fd, header.raw, 10); - - /* Magic header for gzip files, 1F 8B = \037\213 */ - if ((header.formated.magic[0] != 0x1F) - || (header.formated.magic[1] != 0x8b)) { - error_msg_and_die("Invalid gzip magic"); - } + xread_all(src_fd, header.raw, 8); /* Check the compression method */ if (header.formated.method != 8) { diff --git a/archival/libunarchive/data_extract_all.c b/archival/libunarchive/data_extract_all.c index 20d99aa58..a80f422b7 100644 --- a/archival/libunarchive/data_extract_all.c +++ b/archival/libunarchive/data_extract_all.c @@ -18,7 +18,6 @@ extern void data_extract_all(archive_handle_t *archive_handle) if (archive_handle->flags & ARCHIVE_CREATE_LEADING_DIRS) { char *dir = dirname(strdup(file_header->name)); make_directory (dir, 0777, FILEUTILS_RECUR); - free(dir); } /* Create the file */ diff --git a/archival/libunarchive/decompress_uncompress.c b/archival/libunarchive/decompress_uncompress.c index 903e6aa6d..949e27df1 100644 --- a/archival/libunarchive/decompress_uncompress.c +++ b/archival/libunarchive/decompress_uncompress.c @@ -28,8 +28,9 @@ * [... History snipped ...] * */ -#include - +#include +#include +#include #define IBUFSIZ 2048 /* Defailt input buffer size */ #define OBUFSIZ 2048 /* Default output buffer size */ @@ -95,9 +96,6 @@ unsigned short codetab[HSIZE]; #define clear_tab_prefixof() memset(codetab, 0, 256); -extern int uncompress ( FILE *, FILE * ); - - /* * Decompress stdin to stdout. This routine adapts to the codes in the * file building the "string" table on-the-fly; requiring no table to @@ -105,7 +103,7 @@ extern int uncompress ( FILE *, FILE * ); * with those of the compress() routine. See the definitions above. */ -int uncompress ( FILE * fdin, FILE * fdout ) +extern int uncompress(int fd_in, int fd_out) { char_type *stackp; code_int code; @@ -125,7 +123,7 @@ int uncompress ( FILE * fdin, FILE * fdout ) insize = 0; - inbuf [0] = fgetc(fdin); + inbuf [0] = xread_char(fd_in); maxbits = inbuf[0] & BIT_MASK; block_mode = inbuf[0] & BLOCK_MODE; @@ -173,11 +171,7 @@ resetbuf: ; if (insize < (int) sizeof(inbuf)-IBUFSIZ) { - rsize = fread(inbuf+insize, 1,IBUFSIZ,fdin); - - if ( !rsize && ferror(fdin)) - return -1; - + xread_all(fd_in, inbuf+insize, IBUFSIZ); insize += rsize; } @@ -275,8 +269,7 @@ resetbuf: ; if (outpos >= OBUFSIZ) { - fwrite(outbuf, 1,outpos,fdout); - + write(fd_out, outbuf, outpos); outpos = 0; } stackp+= i; @@ -303,8 +296,9 @@ resetbuf: ; } while (rsize > 0); - if (outpos > 0) - fwrite(outbuf, outpos,1, fdout); + if (outpos > 0) { + write(fd_out, outbuf, outpos); + } return 0; } diff --git a/archival/libunarchive/filter_accept_all.c b/archival/libunarchive/filter_accept_all.c index 0471ccef0..2838ea1f2 100644 --- a/archival/libunarchive/filter_accept_all.c +++ b/archival/libunarchive/filter_accept_all.c @@ -6,5 +6,9 @@ */ extern char filter_accept_all(const llist_t *accept_list, const llist_t *reject_list, const char *key) { - return(EXIT_SUCCESS); + if (key) { + return(EXIT_SUCCESS); + } else { + return(EXIT_FAILURE); + } } diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index 2c8fc0aa0..bb0affeb3 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c @@ -155,7 +155,6 @@ extern char get_header_tar(archive_handle_t *archive_handle) # endif } #endif - if (archive_handle->filter(archive_handle->accept, archive_handle->reject, archive_handle->file_header->name) == EXIT_SUCCESS) { archive_handle->action_header(archive_handle->file_header); archive_handle->flags |= ARCHIVE_EXTRACT_QUIET; diff --git a/archival/libunarchive/get_header_tar_gz.c b/archival/libunarchive/get_header_tar_gz.c index c06beac9d..24d19fbfd 100644 --- a/archival/libunarchive/get_header_tar_gz.c +++ b/archival/libunarchive/get_header_tar_gz.c @@ -27,11 +27,17 @@ extern char get_header_tar_gz(archive_handle_t *archive_handle) { int fd_pipe[2]; int pid; + unsigned char magic[2]; + + xread_all(archive_handle->src_fd, &magic, 2); + if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { + error_msg_and_die("Invalid gzip magic"); + } check_header_gzip(archive_handle->src_fd); if (pipe(fd_pipe) != 0) { - error_msg_and_die("Can't create pipe\n"); + error_msg_and_die("Can't create pipe"); } pid = fork(); @@ -54,6 +60,7 @@ extern char get_header_tar_gz(archive_handle_t *archive_handle) archive_handle->src_fd = fd_pipe[0]; + archive_handle->offset = 0; while (get_header_tar(archive_handle) == EXIT_SUCCESS); if (kill(pid, SIGTERM) == -1) { diff --git a/archival/libunarchive/uncompress.c b/archival/libunarchive/uncompress.c index 903e6aa6d..949e27df1 100644 --- a/archival/libunarchive/uncompress.c +++ b/archival/libunarchive/uncompress.c @@ -28,8 +28,9 @@ * [... History snipped ...] * */ -#include - +#include +#include +#include #define IBUFSIZ 2048 /* Defailt input buffer size */ #define OBUFSIZ 2048 /* Default output buffer size */ @@ -95,9 +96,6 @@ unsigned short codetab[HSIZE]; #define clear_tab_prefixof() memset(codetab, 0, 256); -extern int uncompress ( FILE *, FILE * ); - - /* * Decompress stdin to stdout. This routine adapts to the codes in the * file building the "string" table on-the-fly; requiring no table to @@ -105,7 +103,7 @@ extern int uncompress ( FILE *, FILE * ); * with those of the compress() routine. See the definitions above. */ -int uncompress ( FILE * fdin, FILE * fdout ) +extern int uncompress(int fd_in, int fd_out) { char_type *stackp; code_int code; @@ -125,7 +123,7 @@ int uncompress ( FILE * fdin, FILE * fdout ) insize = 0; - inbuf [0] = fgetc(fdin); + inbuf [0] = xread_char(fd_in); maxbits = inbuf[0] & BIT_MASK; block_mode = inbuf[0] & BLOCK_MODE; @@ -173,11 +171,7 @@ resetbuf: ; if (insize < (int) sizeof(inbuf)-IBUFSIZ) { - rsize = fread(inbuf+insize, 1,IBUFSIZ,fdin); - - if ( !rsize && ferror(fdin)) - return -1; - + xread_all(fd_in, inbuf+insize, IBUFSIZ); insize += rsize; } @@ -275,8 +269,7 @@ resetbuf: ; if (outpos >= OBUFSIZ) { - fwrite(outbuf, 1,outpos,fdout); - + write(fd_out, outbuf, outpos); outpos = 0; } stackp+= i; @@ -303,8 +296,9 @@ resetbuf: ; } while (rsize > 0); - if (outpos > 0) - fwrite(outbuf, outpos,1, fdout); + if (outpos > 0) { + write(fd_out, outbuf, outpos); + } return 0; } diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index e1e93988f..9372dc5e1 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c @@ -70,6 +70,7 @@ extern int rpm2cpio_main(int argc, char **argv) { struct rpm_lead lead; int rpm_fd; + unsigned char magic[2]; if (argc == 1) { rpm_fd = fileno(stdin); @@ -88,6 +89,11 @@ extern int rpm2cpio_main(int argc, char **argv) /* Skip the main header */ skip_header(rpm_fd); + + xread_all(rpm_fd, &magic, 2); + if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) + error_msg_and_die("Invalid gzip magic"); + } check_header_gzip(rpm_fd); if (inflate(rpm_fd, fileno(stdout)) != 0) { diff --git a/include/libbb.h b/include/libbb.h index 9dbbb47ce..2fec93db1 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -226,6 +226,7 @@ extern long arith (const char *startbuf, int *errcode); int read_package_field(const char *package_buffer, char **field_name, char **field_value); char *fgets_str(FILE *file, const char *terminating_string); +extern int uncompress(int fd_in, int fd_out); extern int inflate(int in, int out); extern struct hostent *xgethostbyname(const char *name); diff --git a/include/unarchive.h b/include/unarchive.h index e564e9572..023c3e8aa 100644 --- a/include/unarchive.h +++ b/include/unarchive.h @@ -85,7 +85,7 @@ extern char get_header_ar(archive_handle_t *archive_handle); extern char get_header_tar(archive_handle_t *archive_handle); extern char get_header_tar_gz(archive_handle_t *archive_handle); -//extern void seek_sub_file(int src_fd, unsigned int amount); +extern void seek_sub_file(int src_fd, unsigned int amount); extern const unsigned short data_align(const int src_fd, const unsigned int offset, const unsigned short align_to); extern const llist_t *add_to_list(const llist_t *old_head, const char *new_item); extern int copy_file_chunk_fd(int src_fd, int dst_fd, unsigned long long chunksize); diff --git a/libbb/uncompress.c b/libbb/uncompress.c index 903e6aa6d..949e27df1 100644 --- a/libbb/uncompress.c +++ b/libbb/uncompress.c @@ -28,8 +28,9 @@ * [... History snipped ...] * */ -#include - +#include +#include +#include #define IBUFSIZ 2048 /* Defailt input buffer size */ #define OBUFSIZ 2048 /* Default output buffer size */ @@ -95,9 +96,6 @@ unsigned short codetab[HSIZE]; #define clear_tab_prefixof() memset(codetab, 0, 256); -extern int uncompress ( FILE *, FILE * ); - - /* * Decompress stdin to stdout. This routine adapts to the codes in the * file building the "string" table on-the-fly; requiring no table to @@ -105,7 +103,7 @@ extern int uncompress ( FILE *, FILE * ); * with those of the compress() routine. See the definitions above. */ -int uncompress ( FILE * fdin, FILE * fdout ) +extern int uncompress(int fd_in, int fd_out) { char_type *stackp; code_int code; @@ -125,7 +123,7 @@ int uncompress ( FILE * fdin, FILE * fdout ) insize = 0; - inbuf [0] = fgetc(fdin); + inbuf [0] = xread_char(fd_in); maxbits = inbuf[0] & BIT_MASK; block_mode = inbuf[0] & BLOCK_MODE; @@ -173,11 +171,7 @@ resetbuf: ; if (insize < (int) sizeof(inbuf)-IBUFSIZ) { - rsize = fread(inbuf+insize, 1,IBUFSIZ,fdin); - - if ( !rsize && ferror(fdin)) - return -1; - + xread_all(fd_in, inbuf+insize, IBUFSIZ); insize += rsize; } @@ -275,8 +269,7 @@ resetbuf: ; if (outpos >= OBUFSIZ) { - fwrite(outbuf, 1,outpos,fdout); - + write(fd_out, outbuf, outpos); outpos = 0; } stackp+= i; @@ -303,8 +296,9 @@ resetbuf: ; } while (rsize > 0); - if (outpos > 0) - fwrite(outbuf, outpos,1, fdout); + if (outpos > 0) { + write(fd_out, outbuf, outpos); + } return 0; } -- cgit v1.2.3