]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug 4485: off-by-one out-of-bounds Parser::Tokenizer::int64() read errors
authorEduard Bagdasaryan <eduard.bagdasaryan@measurement-factory.com>
Tue, 24 May 2016 20:05:03 +0000 (08:05 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Tue, 24 May 2016 20:05:03 +0000 (08:05 +1200)
src/parser/Tokenizer.cc
src/tests/testTokenizer.cc

index b48ff994586ade3aaec1d061216731c5561f34e3..5842d19af04681e2073c39b5c1c8694f7c8d6678 100644 (file)
@@ -111,8 +111,9 @@ Parser::Tokenizer::int64(int64_t & result, int base)
     } else if (*s == '+') {
         ++s;
     }
+
     if (s >= end) return false;
-    if (( base == 0 || base == 16) && *s == '0' && (s+1 <= end ) &&
+    if (( base == 0 || base == 16) && *s == '0' && (s+1 < end ) &&
             tolower(*(s+1)) == 'x') {
         s += 2;
         base = 16;
@@ -135,7 +136,8 @@ Parser::Tokenizer::int64(int64_t & result, int base)
 
     int any = 0, c;
     int64_t acc = 0;
-    for (c = *s++; s <= end; c = *s++) {
+    do {
+        c = *s;
         if (xisdigit(c)) {
             c -= '0';
         } else if (xisalpha(c)) {
@@ -152,7 +154,7 @@ Parser::Tokenizer::int64(int64_t & result, int base)
             acc *= base;
             acc += c;
         }
-    }
+    } while (++s < end);
 
     if (any == 0) // nothing was parsed
         return false;
@@ -164,6 +166,6 @@ Parser::Tokenizer::int64(int64_t & result, int base)
         acc = -acc;
 
     result = acc;
-    return success(s - buf_.rawContent() - 1);
+    return success(s - buf_.rawContent());
 }
 
index bd895b1a4d0b3799fc5f3134834d174553d69845..d58be977c72ec5f1aa8f7cf13e2b72e9eb79bd87 100644 (file)
@@ -144,6 +144,7 @@ testTokenizer::testTokenizerInt64()
         const int64_t benchmark = 1234;
         CPPUNIT_ASSERT(t.int64(rv, 10));
         CPPUNIT_ASSERT_EQUAL(benchmark,rv);
+        CPPUNIT_ASSERT(t.buf().isEmpty());
     }
 
     // successful parse, autodetect base
@@ -153,6 +154,7 @@ testTokenizer::testTokenizerInt64()
         const int64_t benchmark = 1234;
         CPPUNIT_ASSERT(t.int64(rv));
         CPPUNIT_ASSERT_EQUAL(benchmark,rv);
+        CPPUNIT_ASSERT(t.buf().isEmpty());
     }
 
     // successful parse, autodetect base
@@ -162,6 +164,7 @@ testTokenizer::testTokenizerInt64()
         const int64_t benchmark = 01234;
         CPPUNIT_ASSERT(t.int64(rv));
         CPPUNIT_ASSERT_EQUAL(benchmark,rv);
+        CPPUNIT_ASSERT(t.buf().isEmpty());
     }
 
     // successful parse, autodetect base
@@ -171,6 +174,7 @@ testTokenizer::testTokenizerInt64()
         const int64_t benchmark = 0x12f4;
         CPPUNIT_ASSERT(t.int64(rv));
         CPPUNIT_ASSERT_EQUAL(benchmark,rv);
+        CPPUNIT_ASSERT(t.buf().isEmpty());
     }
 
     // API mismatch: don't eat leading space
@@ -178,6 +182,7 @@ testTokenizer::testTokenizerInt64()
         int64_t rv;
         Parser::Tokenizer t(SBuf(" 1234"));
         CPPUNIT_ASSERT(!t.int64(rv));
+        CPPUNIT_ASSERT_EQUAL(SBuf(" 1234"), t.buf());
     }
 
     // API mismatch: don't eat multiple leading spaces
@@ -185,6 +190,7 @@ testTokenizer::testTokenizerInt64()
         int64_t rv;
         Parser::Tokenizer t(SBuf("  1234"));
         CPPUNIT_ASSERT(!t.int64(rv));
+        CPPUNIT_ASSERT_EQUAL(SBuf("  1234"), t.buf());
     }
 
     // trailing spaces
@@ -222,6 +228,7 @@ testTokenizer::testTokenizerInt64()
         int64_t rv;
         Parser::Tokenizer t(SBuf("1029397752385698678762234"));
         CPPUNIT_ASSERT(!t.int64(rv));
+        CPPUNIT_ASSERT_EQUAL(SBuf("1029397752385698678762234"), t.buf());
     }
 
     // buffered sub-string parsing
@@ -233,6 +240,7 @@ testTokenizer::testTokenizerInt64()
         CPPUNIT_ASSERT_EQUAL(SBuf("22"),t.buf());
         CPPUNIT_ASSERT(t.int64(rv));
         CPPUNIT_ASSERT_EQUAL(benchmark,rv);
+        CPPUNIT_ASSERT(t.buf().isEmpty());
     }
 
     // base-16, prefix