libarchive: add a function to unpack embedded data
No binary (build failed)
—
(log yok)
| @@ -107,7 +107,7 @@ struct bunzip_data { | |
| uint8_t selectors[32768]; /* nSelectors=15 bits */ | |
| struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ | |
| }; | |
| - | /* typedef struct bunzip_data bunzip_data; -- done in .h file */ |
| + | typedef struct bunzip_data bunzip_data; |
| /* Return the next nnn bits of input. All reads from the compressed input | |
| @@ -575,7 +575,7 @@ static int get_next_block(bunzip_data *bd) | |
| in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0. | |
| (Why? This allows to get rid of one local variable) | |
| */ | |
| - | int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) |
| + | static int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) |
| { | |
| const uint32_t *dbuf; | |
| int pos, current, previous; | |
| @@ -699,7 +699,7 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |
| /* Because bunzip2 is used for help text unpacking, and because bb_show_usage() | |
| should work for NOFORK applets too, we must be extremely careful to not leak | |
| any allocations! */ | |
| - | int FAST_FUNC start_bunzip( |
| + | static int FAST_FUNC start_bunzip( |
| void *jmpbuf, | |
| bunzip_data **bdp, | |
| int in_fd, | |
| @@ -759,7 +759,7 @@ int FAST_FUNC start_bunzip( | |
| return RETVAL_OK; | |
| } | |
| - | void FAST_FUNC dealloc_bunzip(bunzip_data *bd) |
| + | static void FAST_FUNC dealloc_bunzip(bunzip_data *bd) |
| { | |
| free(bd->dbuf); | |
| free(bd); | |
| @@ -847,6 +847,36 @@ unpack_bz2_stream(transformer_state_t *xstate) | |
| return i ? i : IF_DESKTOP(total_written) + 0; | |
| } | |
| + | char* FAST_FUNC |
| + | unpack_bz2_data(const char *packed, int packed_len, int unpacked_len) |
| + | { |
| + | char *outbuf = NULL; |
| + | bunzip_data *bd; |
| + | int i; |
| + | jmp_buf jmpbuf; |
| + | |
| + | /* Setup for I/O error handling via longjmp */ |
| + | i = setjmp(jmpbuf); |
| + | if (i == 0) { |
| + | i = start_bunzip(&jmpbuf, |
| + | &bd, |
| + | /* src_fd: */ -1, |
| + | /* inbuf: */ packed, |
| + | /* len: */ packed_len |
| + | ); |
| + | } |
| + | /* read_bunzip can longjmp and end up here with i != 0 |
| + | * on read data errors! Not trivial */ |
| + | if (i == 0) { |
| + | /* Cannot use xmalloc: will leak bd in NOFORK case! */ |
| + | outbuf = malloc_or_warn(unpacked_len); |
| + | if (outbuf) |
| + | read_bunzip(bd, outbuf, unpacked_len); |
| + | } |
| + | dealloc_bunzip(bd); |
| + | return outbuf; |
| + | } |
| + | |
| #ifdef TESTING | |
| static char *const bunzip_errors[] = { | |
| @@ -214,12 +214,7 @@ const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_F | |
| const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_FUNC; | |
| /* A bit of bunzip2 internals are exposed for compressed help support: */ | |
| - | typedef struct bunzip_data bunzip_data; |
| - | int start_bunzip(void *, bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC; |
| - | /* NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes |
| - | * in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0: */ |
| - | int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; |
| - | void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; |
| + | char *unpack_bz2_data(const char *packed, int packed_len, int unpacked_len) FAST_FUNC; |
| /* Meaning and direction (input/output) of the fields are transformer-specific */ | |
| typedef struct transformer_state_t { | |
| @@ -107,34 +107,8 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; | |
| static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; | |
| # include "bb_archive.h" | |
| - | static const char *unpack_usage_messages(void) |
| - | { |
| - | char *outbuf = NULL; |
| - | bunzip_data *bd; |
| - | int i; |
| - | jmp_buf jmpbuf; |
| - | |
| - | /* Setup for I/O error handling via longjmp */ |
| - | i = setjmp(jmpbuf); |
| - | if (i == 0) { |
| - | i = start_bunzip(&jmpbuf, |
| - | &bd, |
| - | /* src_fd: */ -1, |
| - | /* inbuf: */ packed_usage, |
| - | /* len: */ sizeof(packed_usage) |
| - | ); |
| - | } |
| - | /* read_bunzip can longjmp and end up here with i != 0 |
| - | * on read data errors! Not trivial */ |
| - | if (i == 0) { |
| - | /* Cannot use xmalloc: will leak bd in NOFORK case! */ |
| - | outbuf = malloc_or_warn(sizeof(UNPACKED_USAGE)); |
| - | if (outbuf) |
| - | read_bunzip(bd, outbuf, sizeof(UNPACKED_USAGE)); |
| - | } |
| - | dealloc_bunzip(bd); |
| - | return outbuf; |
| - | } |
| + | # define unpack_usage_messages() \ |
| + | unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE)) |
| # define dealloc_usage_messages(s) free(s) | |
| #else | |
| @@ -152,21 +126,23 @@ void FAST_FUNC bb_show_usage(void) | |
| /* Imagine that this applet is "true". Dont suck in printf! */ | |
| const char *usage_string = unpack_usage_messages(); | |
| - | if (*usage_string == '\b') { |
| - | full_write2_str("No help available.\n\n"); |
| - | } else { |
| - | full_write2_str("Usage: "SINGLE_APPLET_STR" "); |
| - | full_write2_str(usage_string); |
| - | full_write2_str("\n\n"); |
| + | if (usage_string) { |
| + | if (*usage_string == '\b') { |
| + | full_write2_str("No help available.\n\n"); |
| + | } else { |
| + | full_write2_str("Usage: "SINGLE_APPLET_STR" "); |
| + | full_write2_str(usage_string); |
| + | full_write2_str("\n\n"); |
| + | } |
| + | if (ENABLE_FEATURE_CLEAN_UP) |
| + | dealloc_usage_messages((char*)usage_string); |
| } | |
| - | if (ENABLE_FEATURE_CLEAN_UP) |
| - | dealloc_usage_messages((char*)usage_string); |
| #else | |
| const char *p; | |
| const char *usage_string = p = unpack_usage_messages(); | |
| int ap = find_applet_by_name(applet_name); | |
| - | if (ap < 0) /* never happens, paranoia */ |
| + | if (ap < 0 || usage_string == NULL) |
| xfunc_die(); | |
| while (ap) { | |
| while (*p++) continue; | |
| @@ -986,38 +962,11 @@ find_script_by_name(const char *name) | |
| return -0x10000; /* make it so that NUM_APPLETS + <error> is still < 0 */ | |
| } | |
| - | static char * |
| - | unpack_scripts(void) |
| - | { |
| - | char *outbuf = NULL; |
| - | bunzip_data *bd; |
| - | int i; |
| - | jmp_buf jmpbuf; |
| - | |
| - | /* Setup for I/O error handling via longjmp */ |
| - | i = setjmp(jmpbuf); |
| - | if (i == 0) { |
| - | i = start_bunzip(&jmpbuf, |
| - | &bd, |
| - | /* src_fd: */ -1, |
| - | /* inbuf: */ packed_scripts, |
| - | /* len: */ sizeof(packed_scripts) |
| - | ); |
| - | } |
| - | /* read_bunzip can longjmp and end up here with i != 0 |
| - | * on read data errors! Not trivial */ |
| - | if (i == 0) { |
| - | outbuf = xmalloc(UNPACKED_SCRIPTS_LENGTH); |
| - | read_bunzip(bd, outbuf, UNPACKED_SCRIPTS_LENGTH); |
| - | } |
| - | dealloc_bunzip(bd); |
| - | return outbuf; |
| - | } |
| - | |
| char* FAST_FUNC | |
| get_script_content(unsigned n) | |
| { | |
| - | char *t = unpack_scripts(); |
| + | char *t = unpack_bz2_data(packed_scripts, sizeof(packed_scripts), |
| + | UNPACKED_SCRIPTS_LENGTH); |
| if (t) { | |
| while (n != 0) { | |
| while (*t++ != '\0') | |
| @@ -43,29 +43,10 @@ int bbconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int bbconfig_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |
| { | |
| #if ENABLE_FEATURE_COMPRESS_BBCONFIG | |
| - | bunzip_data *bd; |
| - | int i; |
| - | jmp_buf jmpbuf; |
| - | |
| - | /* Setup for I/O error handling via longjmp */ |
| - | i = setjmp(jmpbuf); |
| - | if (i == 0) { |
| - | i = start_bunzip(&jmpbuf, |
| - | &bd, |
| - | /* src_fd: */ -1, |
| - | /* inbuf: */ bbconfig_config_bz2, |
| - | /* len: */ sizeof(bbconfig_config_bz2) |
| - | ); |
| - | } |
| - | /* read_bunzip can longjmp and end up here with i != 0 |
| - | * on read data errors! Not trivial */ |
| - | if (i == 0) { |
| - | /* Cannot use xmalloc: will leak bd in NOFORK case! */ |
| - | char *outbuf = malloc_or_warn(sizeof(bbconfig_config)); |
| - | if (outbuf) { |
| - | read_bunzip(bd, outbuf, sizeof(bbconfig_config)); |
| - | full_write1_str(outbuf); |
| - | } |
| + | const char *outbuf = unpack_bz2_data(bbconfig_config_bz2, |
| + | sizeof(bbconfig_config_bz2), sizeof(bbconfig_config)); |
| + | if (outbuf) { |
| + | full_write1_str(outbuf); |
| } | |
| #else | |
| full_write1_str(bbconfig_config); | |