From: Brian Weaver Date: Wed, 26 Sep 2012 15:45:52 +0000 (-0400) Subject: Refactored common code into a single function X-Git-Tag: v3.1.0~41^2~1^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F26%2Fhead;p=thirdparty%2Flibarchive.git Refactored common code into a single function The tar_atol8() and tar_atol10() functions were essentially identical. The code has been refactored to a common function with tar_atol8() and tar_atol10() calling the commont function with the radix instead duplicating the code. The logic was also changed slightly to prevent a pointer dereference when a zero length character array is passed to the conversion routine. --- diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c index ed5799333..8f5059767 100644 --- a/libarchive/archive_read_support_format_tar.c +++ b/libarchive/archive_read_support_format_tar.c @@ -2407,16 +2407,18 @@ tar_atol(const char *p, unsigned char_cnt) * it does obey locale. */ static int64_t -tar_atol8(const char *p, unsigned char_cnt) +tar_atol_base_n(const char *p, unsigned char_cnt, int base) { int64_t l, limit, last_digit_limit; - int digit, sign, base; + int digit, sign; - base = 8; limit = INT64_MAX / base; last_digit_limit = INT64_MAX % base; - while ((*p == ' ' || *p == '\t') && char_cnt != 0) { + /* the pointer will not be dereferenced if char_cnt is zero + * due to the way the && operator is evaulated. + */ + while (char_cnt != 0 && (*p == ' ' || *p == '\t')) { p++; char_cnt--; } @@ -2444,47 +2446,16 @@ tar_atol8(const char *p, unsigned char_cnt) return (sign < 0) ? -l : l; } -/* - * Note that this implementation does not (and should not!) obey - * locale settings; you cannot simply substitute strtol here, since - * it does obey locale. - */ static int64_t -tar_atol10(const char *p, unsigned char_cnt) +tar_atol8(const char *p, unsigned char_cnt) { - int64_t l, limit, last_digit_limit; - int base, digit, sign; - - base = 10; - limit = INT64_MAX / base; - last_digit_limit = INT64_MAX % base; - - while ((*p == ' ' || *p == '\t') && char_cnt != 0) { - p++; - char_cnt--; - } - - sign = 1; - if (char_cnt != 0 && *p == '-') { - sign = -1; - p++; - char_cnt--; - } + return tar_atol_base_n(p, char_cnt, 8); +} - l = 0; - if (char_cnt != 0) { - digit = *p - '0'; - while (digit >= 0 && digit < base && char_cnt != 0) { - if (l > limit || (l == limit && digit > last_digit_limit)) { - l = INT64_MAX; /* Truncate on overflow. */ - break; - } - l = (l * base) + digit; - digit = *++p - '0'; - char_cnt--; - } - } - return (sign < 0) ? -l : l; +static int64_t +tar_atol10(const char *p, unsigned char_cnt) +{ + return tar_atol_base_n(p, char_cnt, 10); } /*