opkg

statically linked package installer
git clone anongit@rnpnr.xyz:opkg.git
Log | Files | Refs | Feed | Submodules | README | LICENSE

0010-pax-Fix-GNU-long-name-handling-with-short-read.patch (4518B)


      1 From ec3fd37495e977af375a98a472d19ae0ccbcd874 Mon Sep 17 00:00:00 2001
      2 From: Michael Forney <mforney@mforney.org>
      3 Date: Sat, 3 Dec 2016 20:49:24 -0800
      4 Subject: [PATCH] pax: Fix GNU long name handling with short read
      5 
      6 ---
      7  bin/pax/ar_subs.c   | 66 +++++++++++++++++++++++++++++++++------------
      8  bin/pax/buf_subs.c  |  4 +--
      9  bin/pax/file_subs.c | 25 +----------------
     10  3 files changed, 51 insertions(+), 44 deletions(-)
     11 
     12 diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c
     13 index e5b0a4ee5d1..f0a55abe2f7 100644
     14 --- a/bin/pax/ar_subs.c
     15 +++ b/bin/pax/ar_subs.c
     16 @@ -37,6 +37,7 @@
     17  #include <sys/types.h>
     18  #include <sys/stat.h>
     19  #include <sys/time.h>
     20 +#include <err.h>
     21  #include <errno.h>
     22  #include <fcntl.h>
     23  #include <signal.h>
     24 @@ -51,6 +52,7 @@
     25  static void wr_archive(ARCHD *, int is_app);
     26  static int get_arc(void);
     27  static int next_head(ARCHD *);
     28 +static int rd_gnu_string(ARCHD *);
     29  extern sigset_t s_mask;
     30  
     31  /*
     32 @@ -93,16 +95,8 @@ list(void)
     33  	 * step through the archive until the format says it is done
     34  	 */
     35  	while (next_head(arcn) == 0) {
     36 -		if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) {
     37 -			/*
     38 -			 * we need to read, to get the real filename
     39 -			 */
     40 -			off_t cnt;
     41 -			if (!rd_wrfile(arcn, arcn->type == PAX_GLF
     42 -			    ? -1 : -2, &cnt))
     43 -				(void)rd_skip(cnt + arcn->pad);
     44 +		if (rd_gnu_string(arcn))
     45  			continue;
     46 -		}
     47  
     48  		/*
     49  		 * check for pattern, and user specified options match.
     50 @@ -208,15 +202,8 @@ extract(void)
     51  	 * says it is done
     52  	 */
     53  	while (next_head(arcn) == 0) {
     54 -		if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) {
     55 -			/*
     56 -			 * we need to read, to get the real filename
     57 -			 */
     58 -			if (!rd_wrfile(arcn, arcn->type == PAX_GLF
     59 -			    ? -1 : -2, &cnt))
     60 -				(void)rd_skip(cnt + arcn->pad);
     61 +		if (rd_gnu_string(arcn))
     62  			continue;
     63 -		}
     64  
     65  		/*
     66  		 * check for pattern, and user specified options match. When
     67 @@ -1243,3 +1230,48 @@ get_arc(void)
     68  	paxwarn(1, "Sorry, unable to determine archive format.");
     69  	return(-1);
     70  }
     71 +
     72 +/*
     73 + * rd_gnu_string()
     74 + * 	Read the file contents into an allocated string if it is a GNU tar
     75 + * 	long link/file.
     76 + * Return:
     77 + * 	1 if gnu string read, 0 otherwise
     78 + */
     79 +
     80 +static int
     81 +rd_gnu_string(ARCHD *arcn)
     82 +{
     83 +	char **strp;
     84 +
     85 +	switch (arcn->type) {
     86 +	case PAX_GLF:
     87 +		strp = &gnu_name_string;
     88 +		break;
     89 +	case PAX_GLL:
     90 +		strp = &gnu_link_string;
     91 +		break;
     92 +	default:
     93 +		strp = NULL;
     94 +		break;
     95 +	}
     96 +	if (!strp)
     97 +		return 0;
     98 +	/*
     99 +	 * we need to read, to get the real filename
    100 +	 */
    101 +	if (*strp)
    102 +		err(1, "WARNING! Major Internal Error! GNU hack Failing!");
    103 +	*strp = malloc(arcn->sb.st_size + 1);
    104 +	if (*strp == NULL) {
    105 +		paxwarn(1, "Out of memory");
    106 +		(void)rd_skip(arcn->skip + arcn->pad);
    107 +	} else if (rd_wrbuf(*strp, arcn->sb.st_size) < arcn->sb.st_size) {
    108 +		free(*strp);
    109 +		*strp = NULL;
    110 +	} else {
    111 +		(*strp)[arcn->sb.st_size] = '\0';
    112 +		(void)rd_skip(arcn->pad);
    113 +	}
    114 +	return 1;
    115 +}
    116 diff --git a/bin/pax/buf_subs.c b/bin/pax/buf_subs.c
    117 index 68534dcbe25..e84f9e0d3d6 100644
    118 --- a/bin/pax/buf_subs.c
    119 +++ b/bin/pax/buf_subs.c
    120 @@ -673,9 +673,7 @@ rd_wrfile(ARCHD *arcn, int ofd, off_t *left)
    121  	 * pass the blocksize of the file being written to the write routine,
    122  	 * if the size is zero, use the default MINFBSZ
    123  	 */
    124 -	if (ofd < 0)
    125 -		sz = PAXPATHLEN + 1;		/* GNU tar long link/file */
    126 -	else if (fstat(ofd, &sb) == 0) {
    127 +	if (fstat(ofd, &sb) == 0) {
    128  		if (sb.st_blksize > 0)
    129  			sz = (int)sb.st_blksize;
    130  	} else
    131 diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
    132 index 89b4872988b..8aa3d249923 100644
    133 --- a/bin/pax/file_subs.c
    134 +++ b/bin/pax/file_subs.c
    135 @@ -919,7 +919,6 @@ file_write(int fd, char *str, int cnt, int *rem, int *isempt, int sz,
    136  	char *end;
    137  	int wcnt;
    138  	char *st = str;
    139 -	char **strp;
    140  
    141  	/*
    142  	 * while we have data to process
    143 @@ -978,29 +977,7 @@ file_write(int fd, char *str, int cnt, int *rem, int *isempt, int sz,
    144  		/*
    145  		 * have non-zero data in this file system block, have to write
    146  		 */
    147 -		switch (fd) {
    148 -		case -1:
    149 -			strp = &gnu_name_string;
    150 -			break;
    151 -		case -2:
    152 -			strp = &gnu_link_string;
    153 -			break;
    154 -		default:
    155 -			strp = NULL;
    156 -			break;
    157 -		}
    158 -		if (strp) {
    159 -			if (*strp)
    160 -				err(1, "WARNING! Major Internal Error! GNU hack Failing!");
    161 -			*strp = malloc(wcnt + 1);
    162 -			if (*strp == NULL) {
    163 -				paxwarn(1, "Out of memory");
    164 -				return(-1);
    165 -			}
    166 -			memcpy(*strp, st, wcnt);
    167 -			(*strp)[wcnt] = '\0';
    168 -			break;
    169 -		} else if (write(fd, st, wcnt) != wcnt) {
    170 +		if (write(fd, st, wcnt) != wcnt) {
    171  			syswarn(1, errno, "Failed write to file %s", name);
    172  			return(-1);
    173  		}
    174 -- 
    175 2.26.2
    176