fix GH #931: make strToInt() more strict in what it accepts

This commit is contained in:
Guenter Obiltschnig 2015-09-09 11:14:29 +02:00
parent aac6aba66c
commit 15f034cbbd
3 changed files with 17 additions and 59 deletions

View File

@ -107,9 +107,6 @@ bool strToInt(const char* pStr, I& result, short base, char thSep = ',')
{
switch (*pStr)
{
case 'x': case 'X':
if (base != 0x10) return false;
case '0':
if (state < STATE_SIGNIFICANT_DIGITS) break;
@ -142,19 +139,12 @@ bool strToInt(const char* pStr, I& result, short base, char thSep = ',')
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
if (base != 0x10) return false;
if (state < STATE_SIGNIFICANT_DIGITS) state = STATE_SIGNIFICANT_DIGITS;
if (result > limitCheck) return false;
result = result * base + (10 + *pStr - 'A');
break;
case 'U':
case 'u':
case 'L':
case 'l':
goto done;
case '.':
if ((base == 10) && (thSep == '.')) break;
else return false;
@ -165,19 +155,13 @@ bool strToInt(const char* pStr, I& result, short base, char thSep = ',')
case ' ':
if ((base == 10) && (thSep == ' ')) break;
case '\t':
case '\n':
case '\v':
case '\f':
case '\r':
goto done;
// fallthrough
default:
return false;
}
}
done:
if ((sign < 0) && (base == 10)) result *= sign;
return true;

View File

@ -22,6 +22,7 @@
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstdint>
using Poco::NumberParser;
@ -69,20 +70,11 @@ void NumberParserTest::testParse()
assert(NumberParser::parse("-123") == -123);
assert(NumberParser::parse("0") == 0);
assert(NumberParser::parse("000") == 0);
assert(NumberParser::parse(" 123 ") == 123);
assert(NumberParser::parse(" 123") == 123);
assert(NumberParser::parse("123 ") == 123);
assert(NumberParser::parse("0123") == 123);
assert(NumberParser::parse("+0123") == 123);
assert(NumberParser::parse("-0123") == -123);
assert(NumberParser::parse("-123") == -123);
assert(NumberParser::parseUnsigned("123") == 123);
assert(NumberParser::parseHex("12AB") == 0x12ab);
assert(NumberParser::parseHex("0X12AB") == 0x12ab);
assert(NumberParser::parseHex("0x12AB") == 0x12ab);
assert(NumberParser::parseHex("0x12aB") == 0x12ab);
assert(NumberParser::parseHex("0X98Fe") == 0x98fe);
assert(NumberParser::parseHex("0x0") == 0);
assert(NumberParser::parseHex("00") == 0);
assert(NumberParser::parseOct("123") == 0123);
assert(NumberParser::parseOct("0123") == 0123);
@ -101,9 +93,9 @@ void NumberParserTest::testParse()
assert(NumberParser::parse64("-123") == -123);
assert(NumberParser::parse64("0123") == 123);
assert(NumberParser::parse64("-0123") == -123);
assert(NumberParser::parse64("123456789123456789") == UINT64_C(123456789123456789));
assert(NumberParser::parseUnsigned64("123") == 123);
assert(NumberParser::parseHex64("12AB") == 0x12ab);
assert(NumberParser::parseHex64("0x12AB") == 0x12ab);
assert(NumberParser::parseOct64("123") == 0123);
assert(NumberParser::parseOct64("0123") == 0123);
#endif
@ -155,35 +147,26 @@ void NumberParserTest::testParse()
assertEqualDelta(d, NumberParser::parseFloat(format("-1%c234e+100", dp), dp, ts), 0.01);
assertEqualDelta(d, NumberParser::parseFloat(format("-1%c234E100", dp), dp, ts), 0.01);
d = 1.234e-100;
assertEqualDelta(d, NumberParser::parseFloat(format(" 1%c234e-100 ", dp), dp, ts), 0.01);
assertEqualDelta(d, NumberParser::parseFloat(format(" 1%c234e-100 ", dp), dp, ts), 0.01);
assertEqualDelta(d, NumberParser::parseFloat(format(" 1%c234e-100 ", dp), dp, ts), 0.01);
d = 1234.234e-100;
assertEqualDelta(d, NumberParser::parseFloat(format(" 1%c234%c234e-100 ", ts, dp), dp, ts), 0.01);
assertEqualDelta(d, NumberParser::parseFloat(format("1%c234%c234e-100", ts, dp), dp, ts), 0.01);
d = 12345.234e-100;
assertEqualDelta(d, NumberParser::parseFloat(format(" 12%c345%c234e-100 ", ts, dp), dp, ts), 0.01);
assertEqualDelta(d, NumberParser::parseFloat(format("12%c345%c234e-100", ts, dp), dp, ts), 0.01);
d = 123456.234e-100;
assertEqualDelta(d, NumberParser::parseFloat(format(" 123%c456%c234e-100 ", ts, dp), dp, ts), 0.01);
assertEqualDelta(d, NumberParser::parseFloat(format("123%c456%c234e-100", ts, dp), dp, ts), 0.01);
d = -1234.234e-100;
assertEqualDelta(d, NumberParser::parseFloat(format(" -1%c234%c234e-100 ", ts, dp), dp, ts), 0.01);
assertEqualDelta(d, NumberParser::parseFloat(format("-1%c234%c234e-100", ts, dp), dp, ts), 0.01);
d = -12345.234e-100;
assertEqualDelta(d, NumberParser::parseFloat(format(" -12%c345%c234e-100 ", ts, dp), dp, ts), 0.01);
assertEqualDelta(d, NumberParser::parseFloat(format("-12%c345%c234e-100", ts, dp), dp, ts), 0.01);
d = -123456.234e-100;
assertEqualDelta(d, NumberParser::parseFloat(format(" -123%c456%c234e-100 ", ts, dp), dp, ts), 0.01);
assertEqualDelta(d, NumberParser::parseFloat(format("-123%c456%c234e-100", ts, dp), dp, ts), 0.01);
}
double d = 12.34e-10;
assertEqualDelta(d, NumberParser::parseFloat(format("12%c34e-10", dp), dp, ts), 0.01);
assertEqualDelta(-12.34, NumberParser::parseFloat(format("-12%c34", dp), dp, ts), 0.01);
assertEqualDelta(12.34, NumberParser::parseFloat(format(" 12%c34", dp),dp, ts), 0.01);
assertEqualDelta(12.34, NumberParser::parseFloat(format("12%c34 ", dp), dp, ts), 0.01);
assertEqualDelta(12.34, NumberParser::parseFloat(format(" 12%c34 ", dp), dp, ts), 0.01);
assertEqualDelta(12.34, NumberParser::parseFloat(format("\t\n 12%c34 \v\f\r", dp), dp, ts), 0.01);
assertEqualDelta(12.34, NumberParser::parseFloat(format("12%c34", dp), dp, ts), 0.01);
}
}
#endif // POCO_NO_FPENVIRONMENT
@ -232,6 +215,13 @@ void NumberParserTest::testParseError()
failmsg("must throw SyntaxException");
} catch (SyntaxException&) { }
try
{
NumberParser::parse(" 123");
NumberParser::parseBool("");
failmsg("must throw SyntaxException");
} catch (SyntaxException&) { }
try
{
NumberParser::parse("1 1");

View File

@ -76,28 +76,12 @@ private:
assert(Poco::strToInt("0", result, 10)); assert(result == 0);
assert(Poco::strToInt("000", result, 10)); assert(result == 0);
if (123 < std::numeric_limits<T>::max())
{ assert(Poco::strToInt(" 123 ", result, 10)); assert(result == 123); }
if (123 < std::numeric_limits<T>::max())
{ assert(Poco::strToInt(" 123", result, 10)); assert(result == 123); }
if (123 < std::numeric_limits<T>::max())
{ assert(Poco::strToInt("123 ", result, 10)); assert(result == 123); }
if (std::numeric_limits<T>::is_signed && (-123 > std::numeric_limits<T>::min()))
{ assert(Poco::strToInt("-123", result, 10)); assert(result == -123); }
if (0x123 < std::numeric_limits<T>::max())
{ assert(Poco::strToInt("123", result, 0x10)); assert(result == 0x123); }
if (0x12ab < std::numeric_limits<T>::max())
{ assert(Poco::strToInt("12AB", result, 0x10)); assert(result == 0x12ab); }
if (0x12ab < std::numeric_limits<T>::max())
{ assert(Poco::strToInt("0X12AB", result, 0x10)); assert(result == 0x12ab); }
if (0x12ab < std::numeric_limits<T>::max())
{ assert(Poco::strToInt("0x12AB", result, 0x10)); assert(result == 0x12ab); }
if (0x12ab < std::numeric_limits<T>::max())
{ assert(Poco::strToInt("0x12aB", result, 0x10)); assert(result == 0x12ab); }
if (0x98fe < std::numeric_limits<T>::max())
{ assert(Poco::strToInt("0X98Fe", result, 0x10)); assert(result == 0x98fe); }
if (123 < std::numeric_limits<T>::max())
{ assert(Poco::strToInt("0x0", result, 0x10)); assert(result == 0); }
if (123 < std::numeric_limits<T>::max())
{ assert(Poco::strToInt("00", result, 0x10)); assert(result == 0); }
if (0123 < std::numeric_limits<T>::max())