[PATCH] libarchive: add a function to unpack embedded data

Sam Liddicott sam at liddicott.com
Fri Nov 2 15:41:25 UTC 2018


Will that support an embedded .profile there as well?

Sam

On Fri, 2 Nov 2018 at 13:19, Denys Vlasenko <vda.linux at googlemail.com>
wrote:

> Applied, thanks!
> On Fri, Nov 2, 2018 at 9:34 AM Ron Yorston <rmy at pobox.com> wrote:
> >
> > Similar code to unpack embedded data is used to decompress usage
> > messages, embedded scripts and the config file (in the non-default
> > bbconfig applet).
> >
> > Moving this code to a common function reduces the size of the default
> > build and hides more of the internals of libarchive.
> >
> > function                                             old     new   delta
> > unpack_bz2_data                                        -     135    +135
> > bb_show_usage                                        137     157     +20
> > get_script_content                                    32      47     +15
> > unpack_scripts                                       119       -    -119
> > unpack_usage_messages                                124       -    -124
> >
> ------------------------------------------------------------------------------
> > (add/remove: 1/2 grow/shrink: 2/0 up/down: 170/-243)          Total: -73
> bytes
> >
> > Signed-off-by: Ron Yorston <rmy at pobox.com>
> > ---
> >  archival/libarchive/decompress_bunzip2.c | 38 +++++++++--
> >  include/bb_archive.h                     |  7 +-
> >  libbb/appletlib.c                        | 81 +++++-------------------
> >  miscutils/bbconfig.c                     | 27 ++------
> >  4 files changed, 54 insertions(+), 99 deletions(-)
> >
> > diff --git a/archival/libarchive/decompress_bunzip2.c
> b/archival/libarchive/decompress_bunzip2.c
> > index 7ef4e035f..3deb213a8 100644
> > --- a/archival/libarchive/decompress_bunzip2.c
> > +++ b/archival/libarchive/decompress_bunzip2.c
> > @@ -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;
> >  }
> >
> > +const 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[] = {
> > diff --git a/include/bb_archive.h b/include/bb_archive.h
> > index d2022336b..0dbe17496 100644
> > --- a/include/bb_archive.h
> > +++ b/include/bb_archive.h
> > @@ -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;
> > +const 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 {
> > diff --git a/libbb/appletlib.c b/libbb/appletlib.c
> > index d48b2ea60..6dfaf1f41 100644
> > --- a/libbb/appletlib.c
> > +++ b/libbb/appletlib.c
> > @@ -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')
> > diff --git a/miscutils/bbconfig.c b/miscutils/bbconfig.c
> > index 501349548..11698de94 100644
> > --- a/miscutils/bbconfig.c
> > +++ b/miscutils/bbconfig.c
> > @@ -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);
> > --
> > 2.19.1
> >
> > _______________________________________________
> > busybox mailing list
> > busybox at busybox.net
> > http://lists.busybox.net/mailman/listinfo/busybox
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.busybox.net/pipermail/busybox/attachments/20181102/909d36ac/attachment-0001.html>


More information about the busybox mailing list