libarchive / libarchive

Multi-format archive and compression library

Home Page:http://www.libarchive.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

UUdecode filter does not accept mode with > 3 chars

todd-richmond opened this issue · comments

the uudecode filter is hard-coded to only 3 digits in the file mode, but some encoders use more and the spec is not limited. This patch allows for the common 4 char mode (0777 is common), but a more general fix would be even better

--- libarchive/archive_read_support_filter_uu.c	2024-04-24 17:03:28.035453967 -0700
***************
*** 288,296 ****
  		else
  			l = 0;
  
! 		if (l > 0 && (b[l] < '0' || b[l] > '7' ||
! 		    b[l+1] < '0' || b[l+1] > '7' ||
! 		    b[l+2] < '0' || b[l+2] > '7' || b[l+3] != ' '))
  			l = 0;
  
  		b += len;
--- 288,300 ----
  		else
  			l = 0;
  
! 	    	if (l > 0 && ((b[l+3] == ' ' && (b[l] < '0' || b[l] > '7' ||
! 			b[l+1] < '0' || b[l+1] > '7' || b[l+2] < '0' ||
! 			b[l+2] > '7')) ||
! 			(b[l+4] == ' ' && (b[l] < '0' || b[l] > '1' ||
! 			b[l+1] < '0' || b[l+1] > '7' || b[l+2] < '0' ||
! 			b[l+2] > '7' || b[l+3] < '0' || b[l+3] > '7')) ||
! 			(b[l+3] != ' ' && b[l+4] != ' ')))
  			l = 0;
  
  		b += len;
***************
*** 590,595 ****
--- 594,629 ----
  					    namelen);
  					uudecode->name[namelen] = '\0';
  				}
+ 			} else if (l != 0 && b[l] >= '0' && b[l] <= '1' &&
+ 			    b[l+1] >= '0' && b[l+1] <= '7' &&
+ 			    b[l+2] >= '0' && b[l+2] <= '7' &&
+ 			    b[l+3] >= '0' && b[l+3] <= '7' && b[l+4] == ' ') {
+ 				if (l == 6)
+ 					uudecode->state = ST_READ_UU;
+ 				else
+ 					uudecode->state = ST_READ_BASE64;
+ 				uudecode->mode = (mode_t)(
+ 				    ((int)(b[l+1] - '0') * 64) +
+ 				    ((int)(b[l+2] - '0') * 8) +
+ 				     (int)(b[l+3] - '0'));
+ 				uudecode->mode_set = 1;
+ 				namelen = len - nl - 5 - l;
+ 				if (namelen > 1) {
+ 					if (uudecode->name != NULL)
+ 						free(uudecode->name);
+ 					uudecode->name = malloc(namelen + 1);
+ 			                if (uudecode->name == NULL) {
+ 					archive_set_error(
+ 					    &self->archive->archive,
+ 					    ENOMEM,
+ 					    "Can't allocate data for uudecode");
+ 						return (ARCHIVE_FATAL);
+ 					}
+ 					strncpy(uudecode->name,
+ 					    (const char *)(b + l + 5),
+ 					    namelen);
+ 					uudecode->name[namelen] = '\0';
+ 				}