Skip to content

Commit 0cc7b23

Browse files
committed
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.
1 parent 51870fc commit 0cc7b23

File tree

2 files changed

+10
-11
lines changed

2 files changed

+10
-11
lines changed

src/test/univalue_tests.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(univalue_object)
286286
}
287287

288288
static const char *json1 =
289-
"[1.10000000,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]";
289+
"[1.10000000,{\"key1\":\"str\\u0000\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]";
290290

291291
BOOST_AUTO_TEST_CASE(univalue_readwrite)
292292
{
@@ -306,7 +306,9 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite)
306306
BOOST_CHECK_EQUAL(obj.size(), 3);
307307

308308
BOOST_CHECK(obj["key1"].isStr());
309-
BOOST_CHECK_EQUAL(obj["key1"].getValStr(), "str");
309+
std::string correctValue("str");
310+
correctValue.push_back('\0');
311+
BOOST_CHECK_EQUAL(obj["key1"].getValStr(), correctValue);
310312
BOOST_CHECK(obj["key2"].isNum());
311313
BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800");
312314
BOOST_CHECK(obj["key3"].isObject());

src/univalue/univalue_read.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -188,25 +188,22 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
188188
case 't': valStr += "\t"; break;
189189

190190
case 'u': {
191-
char buf[4] = {0,0,0,0};
192-
char *last = &buf[0];
193191
unsigned int codepoint;
194192
if (hatoui(raw + 1, raw + 1 + 4, codepoint) !=
195193
raw + 1 + 4)
196194
return JTOK_ERR;
197195

198196
if (codepoint <= 0x7f)
199-
*last = (char)codepoint;
197+
valStr.push_back((char)codepoint);
200198
else if (codepoint <= 0x7FF) {
201-
*last++ = (char)(0xC0 | (codepoint >> 6));
202-
*last = (char)(0x80 | (codepoint & 0x3F));
199+
valStr.push_back((char)(0xC0 | (codepoint >> 6)));
200+
valStr.push_back((char)(0x80 | (codepoint & 0x3F)));
203201
} else if (codepoint <= 0xFFFF) {
204-
*last++ = (char)(0xE0 | (codepoint >> 12));
205-
*last++ = (char)(0x80 | ((codepoint >> 6) & 0x3F));
206-
*last = (char)(0x80 | (codepoint & 0x3F));
202+
valStr.push_back((char)(0xE0 | (codepoint >> 12)));
203+
valStr.push_back((char)(0x80 | ((codepoint >> 6) & 0x3F)));
204+
valStr.push_back((char)(0x80 | (codepoint & 0x3F)));
207205
}
208206

209-
valStr += buf;
210207
raw += 4;
211208
break;
212209
}

0 commit comments

Comments
 (0)