1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 12:48:10 +00:00

AK: Fix JsonParser double encoding multibyte utf-8 chararcters

This commit is contained in:
LepkoQQ 2020-06-19 23:46:25 +02:00 committed by Andreas Kling
parent 64513f3c23
commit b1c99c1891
2 changed files with 21 additions and 20 deletions

View file

@ -72,7 +72,7 @@ String JsonParser::consume_quoted_string()
{ {
if (!consume_specific('"')) if (!consume_specific('"'))
return {}; return {};
Vector<u32, 1024> buffer; StringBuilder final_sb;
for (;;) { for (;;) {
size_t peek_index = m_index; size_t peek_index = m_index;
@ -88,8 +88,7 @@ String JsonParser::consume_quoted_string()
if (peek_index != m_index) { if (peek_index != m_index) {
while (peek_index != m_index) { while (peek_index != m_index) {
u32 value = m_input.characters_without_null_termination()[m_index]; final_sb.append(m_input.characters_without_null_termination()[m_index]);
buffer.append(value);
m_index++; m_index++;
} }
} }
@ -99,26 +98,26 @@ String JsonParser::consume_quoted_string()
if (ch == '"') if (ch == '"')
break; break;
if (ch != '\\') { if (ch != '\\') {
buffer.append(consume()); final_sb.append(consume());
continue; continue;
} }
consume(); consume();
char escaped_ch = consume(); char escaped_ch = consume();
switch (escaped_ch) { switch (escaped_ch) {
case 'n': case 'n':
buffer.append('\n'); final_sb.append('\n');
break; break;
case 'r': case 'r':
buffer.append('\r'); final_sb.append('\r');
break; break;
case 't': case 't':
buffer.append('\t'); final_sb.append('\t');
break; break;
case 'b': case 'b':
buffer.append('\b'); final_sb.append('\b');
break; break;
case 'f': case 'f':
buffer.append('\f'); final_sb.append('\f');
break; break;
case 'u': { case 'u': {
StringBuilder sb; StringBuilder sb;
@ -129,27 +128,19 @@ String JsonParser::consume_quoted_string()
auto codepoint = AK::StringUtils::convert_to_uint_from_hex(sb.to_string()); auto codepoint = AK::StringUtils::convert_to_uint_from_hex(sb.to_string());
if (codepoint.has_value()) { if (codepoint.has_value()) {
buffer.append(codepoint.value()); final_sb.append_codepoint(codepoint.value());
} else { } else {
buffer.append('?'); final_sb.append('?');
} }
} break; } break;
default: default:
buffer.append(escaped_ch); final_sb.append(escaped_ch);
break; break;
} }
} }
if (!consume_specific('"')) if (!consume_specific('"'))
return {}; return {};
if (buffer.is_empty())
return String::empty();
StringBuilder final_sb;
for (auto cp : buffer) {
final_sb.append_codepoint(cp);
}
return final_sb.to_string(); return final_sb.to_string();
} }

View file

@ -118,4 +118,14 @@ TEST_CASE(json_utf8_character)
EXPECT_EQ(json.as_string() == "A", true); EXPECT_EQ(json.as_string() == "A", true);
} }
TEST_CASE(json_utf8_multibyte)
{
auto json = JsonValue::from_string("\"š\"").value();
EXPECT_EQ(json.type(), JsonValue::Type::String);
EXPECT_EQ(json.as_string().is_null(), false);
EXPECT_EQ(json.as_string().length(), size_t { 2 });
EXPECT_EQ(json.as_string() == "š", true);
EXPECT_EQ(json.as_string() == "\xc5\xa1", true);
}
TEST_MAIN(JSON) TEST_MAIN(JSON)