diff --git a/src/common.h b/src/common.h index 38f9958e..cbb7906d 100644 --- a/src/common.h +++ b/src/common.h @@ -494,6 +494,12 @@ void buffer_write_global_xheader (void); const char *first_decompress_program (int *pstate); const char *next_decompress_program (int *pstate); +COMMON_INLINE bool +is_octal_digit (char c) +{ + return '0' <= c && c <= '7'; +} + /* Sum values returned by printf to estimate the total bytes output. Estimate -1 if there was a problem, e.g., int overflow or I/O error. */ COMMON_INLINE intmax_t diff --git a/src/list.c b/src/list.c index b0da0cec..6d4dc7ae 100644 --- a/src/list.c +++ b/src/list.c @@ -630,12 +630,6 @@ read_header (union block **return_block, struct tar_stat_info *info, return status; } -static bool -is_octal_digit (char c) -{ - return '0' <= c && c <= '7'; -} - /* Decode things from a file HEADER block into STAT_INFO, also setting *FORMAT_POINTER depending on the header block format. If DO_USER_GROUP, decode the user/group information (this is useful diff --git a/src/misc.c b/src/misc.c index 499ea3e1..6135fff9 100644 --- a/src/misc.c +++ b/src/misc.c @@ -244,19 +244,14 @@ unquote_string (char *string) case '7': { unsigned char value = *source++ - '0'; - - if (*source < '0' || *source > '7') + if (is_octal_digit (*source)) { - *destination++ = value; - break; + value = value * 8 + (*source++ - '0'); + unsigned char val; + if (is_octal_digit (*source) && !ckd_mul (&val, value, 8)) + value = val + (*source++ - '0'); } - unsigned char val1 = value * 8 + (*source++ - '0'), val2; - if (*source < '0' || *source > '7' || ckd_mul (&val2, val1, 8)) - { - *destination++ = value; - break; - } - *destination++ = val2 + (*source++ - '0'); + *destination++ = value; break; }