Fix univalue handling of \u0000 characters.

Univalue's parsing of \u escape sequences did not handle NUL characters
correctly.  They were, effectively, dropped.  The extended test-case
fails with the old code, and is fixed with this patch.
This commit is contained in:
Daniel Kraft 2015-06-10 14:57:57 +02:00
parent 51870fc151
commit 0cc7b2352e
2 changed files with 10 additions and 11 deletions

View File

@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(univalue_object)
} }
static const char *json1 = static const char *json1 =
"[1.10000000,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]"; "[1.10000000,{\"key1\":\"str\\u0000\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]";
BOOST_AUTO_TEST_CASE(univalue_readwrite) BOOST_AUTO_TEST_CASE(univalue_readwrite)
{ {
@ -306,7 +306,9 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite)
BOOST_CHECK_EQUAL(obj.size(), 3); BOOST_CHECK_EQUAL(obj.size(), 3);
BOOST_CHECK(obj["key1"].isStr()); BOOST_CHECK(obj["key1"].isStr());
BOOST_CHECK_EQUAL(obj["key1"].getValStr(), "str"); std::string correctValue("str");
correctValue.push_back('\0');
BOOST_CHECK_EQUAL(obj["key1"].getValStr(), correctValue);
BOOST_CHECK(obj["key2"].isNum()); BOOST_CHECK(obj["key2"].isNum());
BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800"); BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800");
BOOST_CHECK(obj["key3"].isObject()); BOOST_CHECK(obj["key3"].isObject());

View File

@ -188,25 +188,22 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
case 't': valStr += "\t"; break; case 't': valStr += "\t"; break;
case 'u': { case 'u': {
char buf[4] = {0,0,0,0};
char *last = &buf[0];
unsigned int codepoint; unsigned int codepoint;
if (hatoui(raw + 1, raw + 1 + 4, codepoint) != if (hatoui(raw + 1, raw + 1 + 4, codepoint) !=
raw + 1 + 4) raw + 1 + 4)
return JTOK_ERR; return JTOK_ERR;
if (codepoint <= 0x7f) if (codepoint <= 0x7f)
*last = (char)codepoint; valStr.push_back((char)codepoint);
else if (codepoint <= 0x7FF) { else if (codepoint <= 0x7FF) {
*last++ = (char)(0xC0 | (codepoint >> 6)); valStr.push_back((char)(0xC0 | (codepoint >> 6)));
*last = (char)(0x80 | (codepoint & 0x3F)); valStr.push_back((char)(0x80 | (codepoint & 0x3F)));
} else if (codepoint <= 0xFFFF) { } else if (codepoint <= 0xFFFF) {
*last++ = (char)(0xE0 | (codepoint >> 12)); valStr.push_back((char)(0xE0 | (codepoint >> 12)));
*last++ = (char)(0x80 | ((codepoint >> 6) & 0x3F)); valStr.push_back((char)(0x80 | ((codepoint >> 6) & 0x3F)));
*last = (char)(0x80 | (codepoint & 0x3F)); valStr.push_back((char)(0x80 | (codepoint & 0x3F)));
} }
valStr += buf;
raw += 4; raw += 4;
break; break;
} }