JSON bug fixes

GH #241: SF #620 Endless loop in JSON parser (added Buffer::setCapacity)
GH #242: SF #619 Syntax error in JSON parser (float/double trim)
This commit is contained in:
Aleksandar Fabijanic 2013-07-21 22:18:56 -05:00
parent 996ddf1b43
commit 20e1cf8821
8 changed files with 56 additions and 4 deletions

View File

@ -142,7 +142,7 @@ public:
{
T* ptr = new T[newCapacity];
if (preserveContent)
std::memcpy(ptr, _ptr, _capacity);
std::memcpy(ptr, _ptr, _used);
delete [] _ptr;
_ptr = ptr;
@ -151,6 +151,35 @@ public:
_used = newCapacity;
}
void setCapacity(std::size_t newCapacity, bool preserveContent = true)
/// Sets the buffer capacity. If preserveContent is true,
/// the content of the old buffer is copied over to the
/// new buffer. The new capacity can be larger or smaller than
/// the current one; size will be set to the new capacity only if
/// new capacity is smaller than the current size, otherwise it will
/// remain intact.
///
/// Buffers only wrapping externally owned storage can not be
/// resized. If resize is attempted on those, IllegalAccessException
/// is thrown.
{
if (!_ownMem)
throw Poco::InvalidAccessException("Cannot resize buffer which does not own its storage.");
if (newCapacity != _capacity)
{
T* ptr = new T[newCapacity];
if (preserveContent)
std::memcpy(ptr, _ptr, _used < newCapacity ? _used : newCapacity);
delete [] _ptr;
_ptr = ptr;
_capacity = newCapacity;
if (newCapacity < _used) _used = newCapacity;
}
}
void assign(const T* buf, std::size_t sz)
/// Assigns the argument buffer to this buffer.

View File

@ -233,6 +233,7 @@ bool strToFloat(const std::string& str, float& result, char decSep, char thSep)
using namespace double_conversion;
std::string tmp(str);
trimInPlace(tmp);
removeInPlace(tmp, thSep);
removeInPlace(tmp, 'f');
replaceInPlace(tmp, decSep, '.');
@ -249,6 +250,7 @@ bool strToDouble(const std::string& str, double& result, char decSep, char thSep
using namespace double_conversion;
std::string tmp(str);
trimInPlace(tmp);
removeInPlace(tmp, thSep);
replaceInPlace(tmp, decSep, '.');
removeInPlace(tmp, 'f');

View File

@ -266,6 +266,14 @@ void CoreTest::testBuffer()
assert (b.size() == s*2);
assert (b.capacity() == s*2);
b.setCapacity(s * 4);
assert (b.size() == s*2);
assert (b.capacity() == s*4);
b.setCapacity(s);
assert (b.size() == s);
assert (b.capacity() == s);
#if ENABLE_BUGCHECK_TEST
try { int i = b[s]; fail ("must fail"); }
catch (Exception&) { }

View File

@ -202,6 +202,8 @@ void NumberParserTest::testParse()
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);
}
}
#endif // POCO_NO_FPENVIRONMENT

View File

@ -729,7 +729,7 @@ inline void Parser::assertNonContainer()
inline void Parser::growBuffer()
{
_parseBuffer.resize(_parseBuffer.size() * 2, true);
_parseBuffer.setCapacity(_parseBuffer.size() * 2, true);
}

View File

@ -180,7 +180,8 @@ Dynamic::Var Parser::parse(const std::string& json)
int c = 0;
while(source.nextChar(c))
{
if (0 == parseChar(c, source)) throw SyntaxException("JSON syntax error");
if (0 == parseChar(c, source))
throw SyntaxException("JSON syntax error");
}
if (!done())
@ -253,7 +254,7 @@ void Parser::parseBufferPopBackChar()
void Parser::parseBufferPushBackChar(char c)
{
if (_parseBuffer.size() + 1 >= _parseBuffer.capacity())
_parseBuffer.resize(_parseBuffer.capacity() * 2);
_parseBuffer.setCapacity(_parseBuffer.capacity() * 2);
_parseBuffer.append(c);
}

View File

@ -1647,6 +1647,14 @@ void JSONTest::testUnicode()
}
void JSONTest::testSmallBuffer()
{
Poco::JSON::Parser parser(new Poco::JSON::ParseHandler(), 4);
std::string jsonStr = "{ \"x\" : \"123456789012345678901234567890123456789012345678901234567890\" }";
parser.parse(jsonStr);
}
std::string JSONTest::getTestFilesPath(const std::string& type)
{
std::ostringstream ostr;
@ -1717,6 +1725,7 @@ CppUnit::Test* JSONTest::suite()
CppUnit_addTest(pSuite, JSONTest, testInvalidUnicodeJanssonFiles);
CppUnit_addTest(pSuite, JSONTest, testTemplate);
CppUnit_addTest(pSuite, JSONTest, testUnicode);
CppUnit_addTest(pSuite, JSONTest, testSmallBuffer);
return pSuite;
}

View File

@ -86,6 +86,7 @@ public:
void testItunes();
void testUnicode();
void testInvalidUnicodeJanssonFiles();
void testSmallBuffer();
void setUp();
void tearDown();