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';
+ }