Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[Squash] add test, better escaping[Squash] add test, better escaping
  • Loading branch information
jasnell committed Jul 11, 2018
commit 629f936db19ba42780181401caf5a409d8b07e45
69 changes: 50 additions & 19 deletions src/tracing/traced_value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include <stdio.h>
#include <string>

#include <unicode/utf8.h>
#include <unicode/utypes.h>

#if defined(_STLP_VENDOR_CSTD)
// STLPort doesn't import fpclassify into the std namespace.
#define FPCLASSIFY_NAMESPACE
Expand All @@ -21,36 +24,64 @@ namespace tracing {

namespace {

void EscapeAndAppendString(const char* value, std::string* result) {
*result += '"';
std::string EscapeString(const char* value) {
std::string result;
result += '"';
char number_buffer[10];
#if defined(NODE_HAVE_I18N_SUPPORT)
int32_t len = strlen(value);
int32_t p = 0;
int32_t i = 0;
for (;i < len; p = i) {
UChar32 c;
U8_NEXT_OR_FFFD(value, i, len, c);
switch (c) {
case '\b': result += "\\b"; break;
case '\f': result += "\\f"; break;
case '\n': result += "\\n"; break;
case '\r': result += "\\r"; break;
case '\t': result += "\\t"; break;
case '\\': result += "\\\\"; break;
case '"': result += "\\\""; break;
default:
if (c < 32 || c > 126) {
snprintf(
number_buffer, arraysize(number_buffer), "\\u%04X",
static_cast<uint16_t>(static_cast<uint16_t>(c)));
result += number_buffer;
} else {
result.append(value + p, i - p);
}
}
}
#else
// If we do not have ICU, use a modified version of the non-UTF8 aware
// code from V8's own TracedValue implementation. Note, however, This
// will not produce correctly serialized results for UTF8 values.
while (*value) {
char c = *value++;
switch (c) {
case '\t':
*result += "\\t";
break;
case '\n':
*result += "\\n";
break;
case '\"':
*result += "\\\"";
break;
case '\\':
*result += "\\\\";
break;
case '\b': result += "\\b"; break;
case '\f': result += "\\f"; break;
case '\n': result += "\\n"; break;
case '\r': result += "\\r"; break;
case '\t': result += "\\t"; break;
case '\\': result += "\\\\"; break;
case '"': result += "\\\""; break;
default:
if (c < '\x20') {
snprintf(
number_buffer, arraysize(number_buffer), "\\u%04X",
static_cast<unsigned>(static_cast<unsigned char>(c)));
*result += number_buffer;
result += number_buffer;
} else {
*result += c;
result += c;
}
}
}
*result += '"';
#endif // defined(NODE_HAVE_I18N_SUPPORT)
result += '"';
return result;
}

std::string DoubleToCString(double v) {
Expand Down Expand Up @@ -104,7 +135,7 @@ void TracedValue::SetNull(const char* name) {

void TracedValue::SetString(const char* name, const char* value) {
WriteName(name);
EscapeAndAppendString(value, &data_);
data_ += EscapeString(value);
}

void TracedValue::BeginDictionary(const char* name) {
Expand Down Expand Up @@ -141,7 +172,7 @@ void TracedValue::AppendNull() {

void TracedValue::AppendString(const char* value) {
WriteComma();
EscapeAndAppendString(value, &data_);
data_ += EscapeString(value);
}

void TracedValue::BeginDictionary() {
Expand Down
42 changes: 40 additions & 2 deletions test/cctest/test_traced_value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ TEST(TracedValue, Object) {
"1.23e+07,\"h\":false,\"i\":true,\"j\":null,\"k\":"
"{\"l\":\"m\"}}";

EXPECT_EQ(string, check);
EXPECT_EQ(check, string);
}

TEST(TracedValue, Array) {
Expand All @@ -59,5 +59,43 @@ TEST(TracedValue, Array) {
"\"-Infinity\",1.23e+07,false,true,null,"
"{\"foo\":[]}]";

EXPECT_EQ(string, check);
EXPECT_EQ(check, string);
}

TEST(TracedValue, EscapingObject) {
// Verify that special characters in the value are escaped properly
auto traced_value = TracedValue::Create();
traced_value->SetString("a", "1\u20ac23\"\u0001\b\f\n\r\t\\");

std::string string;
traced_value->AppendAsTraceFormat(&string);

#if defined(NODE_HAVE_I18N_SUPPORT)
static const char* check =
"{\"a\":\"1\\u20AC23\\\"\\u0001\\b\\f\\n\\r\\t\\\\\"}";
#else
static const char* check =
"{\"a\":\"1\\u00E2\\u0082\\u00AC23\\\"\\u0001\\b\\f\\n\\r\\t\\\\\"}";
#endif

EXPECT_EQ(check, string);
}

TEST(TracedValue, EscapingArray) {
// Verify that special characters in the value are escaped properly
auto traced_value = TracedValue::CreateArray();
traced_value->AppendString("1\u20ac23\"\u0001\b\f\n\r\t\\");

std::string string;
traced_value->AppendAsTraceFormat(&string);

#if defined(NODE_HAVE_I18N_SUPPORT)
static const char* check =
"[\"1\\u20AC23\\\"\\u0001\\b\\f\\n\\r\\t\\\\\"]";
#else
static const char* check =
"[\"1\\u00E2\\u0082\\u00AC23\\\"\\u0001\\b\\f\\n\\r\\t\\\\\"]";
#endif

EXPECT_EQ(check, string);
}