mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
src,test: fix JSON escaping in node-report
Previously only simple escape sequences were handled (i.e. \n, \t, r etc.). This commit adds escaping of other control symbols in the range of 0x00 to 0x20. Also, this replaces multiple find+replace calls with a single pass replacer. PR-URL: https://github.com/nodejs/node/pull/25626 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Richard Lau <riclau@uk.ibm.com>
This commit is contained in:
committed by
Daniel Bevenius
parent
f8d52c25c4
commit
80441c8086
1
node.gyp
1
node.gyp
@@ -980,6 +980,7 @@
|
||||
'test/cctest/test_node_postmortem_metadata.cc',
|
||||
'test/cctest/test_environment.cc',
|
||||
'test/cctest/test_platform.cc',
|
||||
'test/cctest/test_report_util.cc',
|
||||
'test/cctest/test_traced_value.cc',
|
||||
'test/cctest/test_util.cc',
|
||||
'test/cctest/test_url.cc'
|
||||
|
||||
@@ -214,29 +214,42 @@ void WalkHandle(uv_handle_t* h, void* arg) {
|
||||
writer->json_end();
|
||||
}
|
||||
|
||||
static std::string findAndReplace(const std::string& str,
|
||||
const std::string& old,
|
||||
const std::string& neu) {
|
||||
std::string ret = str;
|
||||
std::string EscapeJsonChars(const std::string& str) {
|
||||
const std::string control_symbols[0x20] = {
|
||||
"\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005",
|
||||
"\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\v", "\\f", "\\r",
|
||||
"\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013",
|
||||
"\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019",
|
||||
"\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f"
|
||||
};
|
||||
|
||||
std::string ret = "";
|
||||
size_t last_pos = 0;
|
||||
size_t pos = 0;
|
||||
while ((pos = ret.find(old, pos)) != std::string::npos) {
|
||||
ret.replace(pos, old.length(), neu);
|
||||
pos += neu.length();
|
||||
for (; pos < str.size(); ++pos) {
|
||||
std::string replace;
|
||||
char ch = str[pos];
|
||||
if (ch == '\\') {
|
||||
replace = "\\\\";
|
||||
} else if (ch == '\"') {
|
||||
replace = "\\\"";
|
||||
} else {
|
||||
size_t num = static_cast<size_t>(ch);
|
||||
if (num < 0x20) replace = control_symbols[num];
|
||||
}
|
||||
if (!replace.empty()) {
|
||||
if (pos > last_pos) {
|
||||
ret += str.substr(last_pos, pos - last_pos);
|
||||
}
|
||||
last_pos = pos + 1;
|
||||
ret += replace;
|
||||
}
|
||||
}
|
||||
// Append any remaining symbols.
|
||||
if (last_pos < str.size()) {
|
||||
ret += str.substr(last_pos, pos - last_pos);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string EscapeJsonChars(const std::string& str) {
|
||||
std::string ret = str;
|
||||
ret = findAndReplace(ret, "\\", "\\\\");
|
||||
ret = findAndReplace(ret, "\\u", "\\u");
|
||||
ret = findAndReplace(ret, "\n", "\\n");
|
||||
ret = findAndReplace(ret, "\f", "\\f");
|
||||
ret = findAndReplace(ret, "\r", "\\r");
|
||||
ret = findAndReplace(ret, "\b", "\\b");
|
||||
ret = findAndReplace(ret, "\t", "\\t");
|
||||
ret = findAndReplace(ret, "\"", "\\\"");
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace report
|
||||
|
||||
26
test/cctest/test_report_util.cc
Normal file
26
test/cctest/test_report_util.cc
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "node_report.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(ReportUtilTest, EscapeJsonChars) {
|
||||
using report::EscapeJsonChars;
|
||||
EXPECT_EQ("abc", EscapeJsonChars("abc"));
|
||||
EXPECT_EQ("abc\\n", EscapeJsonChars("abc\n"));
|
||||
EXPECT_EQ("abc\\nabc", EscapeJsonChars("abc\nabc"));
|
||||
EXPECT_EQ("abc\\\\", EscapeJsonChars("abc\\"));
|
||||
EXPECT_EQ("abc\\\"", EscapeJsonChars("abc\""));
|
||||
|
||||
const std::string expected[0x20] = {
|
||||
"\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005",
|
||||
"\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\v", "\\f", "\\r",
|
||||
"\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013",
|
||||
"\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019",
|
||||
"\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f"
|
||||
};
|
||||
for (int i = 0; i < 0x20; ++i) {
|
||||
char symbols[1] = { static_cast<char>(i) };
|
||||
std::string input(symbols, 1);
|
||||
EXPECT_EQ(expected[i], EscapeJsonChars(input));
|
||||
EXPECT_EQ("a" + expected[i], EscapeJsonChars("a" + input));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user