From: Eduard Bagdasaryan Date: Mon, 23 May 2016 12:35:06 +0000 (+1200) Subject: Bug 4485: off-by-one out-of-bounds Parser::Tokenizer::int64() read errors X-Git-Tag: SQUID_4_0_11~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=566c0b2b44bacdaafa6c7f6f8872825d8faefd48;p=thirdparty%2Fsquid.git Bug 4485: off-by-one out-of-bounds Parser::Tokenizer::int64() read errors --- diff --git a/src/parser/Tokenizer.cc b/src/parser/Tokenizer.cc index 9ce51de42d..c978742c4a 100644 --- a/src/parser/Tokenizer.cc +++ b/src/parser/Tokenizer.cc @@ -227,7 +227,7 @@ Parser::Tokenizer::int64(int64_t & result, int base, bool allowSign, const SBuf: } 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; @@ -250,7 +250,8 @@ Parser::Tokenizer::int64(int64_t & result, int base, bool allowSign, const SBuf: 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)) { @@ -267,7 +268,7 @@ Parser::Tokenizer::int64(int64_t & result, int base, bool allowSign, const SBuf: acc *= base; acc += c; } - } + } while (++s < end); if (any == 0) // nothing was parsed return false; @@ -279,6 +280,6 @@ Parser::Tokenizer::int64(int64_t & result, int base, bool allowSign, const SBuf: acc = -acc; result = acc; - return success(s - range.rawContent() - 1); + return success(s - range.rawContent()); } diff --git a/src/tests/testTokenizer.cc b/src/tests/testTokenizer.cc index cafaefd0e6..edf85d3bb0 100644 --- a/src/tests/testTokenizer.cc +++ b/src/tests/testTokenizer.cc @@ -204,6 +204,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 @@ -213,6 +214,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 @@ -222,6 +224,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 @@ -231,6 +234,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 @@ -238,6 +242,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 @@ -245,6 +250,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 @@ -282,6 +288,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 @@ -293,6 +300,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