]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Refactored common code into a single function 26/head
authorBrian Weaver <cmdrclueless@gmail.com>
Wed, 26 Sep 2012 15:45:52 +0000 (11:45 -0400)
committerBrian Weaver <cmdrclueless@gmail.com>
Wed, 26 Sep 2012 15:45:52 +0000 (11:45 -0400)
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.

libarchive/archive_read_support_format_tar.c

index ed5799333dde4dc21d41e5b83f91c6b039cb37cf..8f505976737542e5c9ea46a03123c78174aaa47a 100644 (file)
@@ -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);
 }
 
 /*