Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4b43eea

Browse filesBrowse files
lundibundiaddaleax
authored andcommitted
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: #25626 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Richard Lau <riclau@uk.ibm.com>
1 parent f33d705 commit 4b43eea
Copy full SHA for 4b43eea

File tree

Expand file treeCollapse file tree

3 files changed

+60
-20
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+60
-20
lines changed
Open diff view settings
Collapse file

‎node.gyp‎

Copy file name to clipboardExpand all lines: node.gyp
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,7 @@
981981
'test/cctest/test_node_postmortem_metadata.cc',
982982
'test/cctest/test_environment.cc',
983983
'test/cctest/test_platform.cc',
984+
'test/cctest/test_report_util.cc',
984985
'test/cctest/test_traced_value.cc',
985986
'test/cctest/test_util.cc',
986987
'test/cctest/test_url.cc'
Collapse file

‎src/node_report_utils.cc‎

Copy file name to clipboardExpand all lines: src/node_report_utils.cc
+33-20Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -214,28 +214,41 @@ void WalkHandle(uv_handle_t* h, void* arg) {
214214
writer->json_end();
215215
}
216216

217-
static std::string findAndReplace(const std::string& str,
218-
const std::string& old,
219-
const std::string& neu) {
220-
std::string ret = str;
217+
std::string EscapeJsonChars(const std::string& str) {
218+
const std::string control_symbols[0x20] = {
219+
"\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005",
220+
"\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\v", "\\f", "\\r",
221+
"\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013",
222+
"\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019",
223+
"\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f"
224+
};
225+
226+
std::string ret = "";
227+
size_t last_pos = 0;
221228
size_t pos = 0;
222-
while ((pos = ret.find(old, pos)) != std::string::npos) {
223-
ret.replace(pos, old.length(), neu);
224-
pos += neu.length();
229+
for (; pos < str.size(); ++pos) {
230+
std::string replace;
231+
char ch = str[pos];
232+
if (ch == '\\') {
233+
replace = "\\\\";
234+
} else if (ch == '\"') {
235+
replace = "\\\"";
236+
} else {
237+
size_t num = static_cast<size_t>(ch);
238+
if (num < 0x20) replace = control_symbols[num];
239+
}
240+
if (!replace.empty()) {
241+
if (pos > last_pos) {
242+
ret += str.substr(last_pos, pos - last_pos);
243+
}
244+
last_pos = pos + 1;
245+
ret += replace;
246+
}
247+
}
248+
// Append any remaining symbols.
249+
if (last_pos < str.size()) {
250+
ret += str.substr(last_pos, pos - last_pos);
225251
}
226-
return ret;
227-
}
228-
229-
std::string EscapeJsonChars(const std::string& str) {
230-
std::string ret = str;
231-
ret = findAndReplace(ret, "\\", "\\\\");
232-
ret = findAndReplace(ret, "\\u", "\\u");
233-
ret = findAndReplace(ret, "\n", "\\n");
234-
ret = findAndReplace(ret, "\f", "\\f");
235-
ret = findAndReplace(ret, "\r", "\\r");
236-
ret = findAndReplace(ret, "\b", "\\b");
237-
ret = findAndReplace(ret, "\t", "\\t");
238-
ret = findAndReplace(ret, "\"", "\\\"");
239252
return ret;
240253
}
241254

Collapse file

‎test/cctest/test_report_util.cc‎

Copy file name to clipboard
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "node_report.h"
2+
3+
#include "gtest/gtest.h"
4+
5+
TEST(ReportUtilTest, EscapeJsonChars) {
6+
using report::EscapeJsonChars;
7+
EXPECT_EQ("abc", EscapeJsonChars("abc"));
8+
EXPECT_EQ("abc\\n", EscapeJsonChars("abc\n"));
9+
EXPECT_EQ("abc\\nabc", EscapeJsonChars("abc\nabc"));
10+
EXPECT_EQ("abc\\\\", EscapeJsonChars("abc\\"));
11+
EXPECT_EQ("abc\\\"", EscapeJsonChars("abc\""));
12+
13+
const std::string expected[0x20] = {
14+
"\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005",
15+
"\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\v", "\\f", "\\r",
16+
"\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013",
17+
"\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019",
18+
"\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f"
19+
};
20+
for (int i = 0; i < 0x20; ++i) {
21+
char symbols[1] = { static_cast<char>(i) };
22+
std::string input(symbols, 1);
23+
EXPECT_EQ(expected[i], EscapeJsonChars(input));
24+
EXPECT_EQ("a" + expected[i], EscapeJsonChars("a" + input));
25+
}
26+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.