Skip to content

Commit 2740c4f

Browse files
committed
Merge branch '2015_11_escape_plan' into bitcoin
2 parents 46098ee + 7482163 commit 2740c4f

File tree

6 files changed

+58
-35
lines changed

6 files changed

+58
-35
lines changed

Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ TEST_FILES = \
8282
$(TEST_DATA_DIR)/fail9.json \
8383
$(TEST_DATA_DIR)/pass1.json \
8484
$(TEST_DATA_DIR)/pass2.json \
85-
$(TEST_DATA_DIR)/pass3.json
85+
$(TEST_DATA_DIR)/pass3.json \
86+
$(TEST_DATA_DIR)/round1.json
8687

8788
EXTRA_DIST=$(TEST_FILES) $(GEN_SRCS)

gen/gen.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,25 @@
1515
using namespace std;
1616

1717
static bool initEscapes;
18-
static const char *escapes[256];
18+
static std::string escapes[256];
1919

2020
static void initJsonEscape()
2121
{
22+
// Escape all lower control characters (some get overridden with smaller sequences below)
23+
for (int ch=0x00; ch<0x20; ++ch) {
24+
char tmpbuf[20];
25+
snprintf(tmpbuf, sizeof(tmpbuf), "\\u%04x", ch);
26+
escapes[ch] = std::string(tmpbuf);
27+
}
28+
2229
escapes[(int)'"'] = "\\\"";
2330
escapes[(int)'\\'] = "\\\\";
2431
escapes[(int)'\b'] = "\\b";
2532
escapes[(int)'\f'] = "\\f";
2633
escapes[(int)'\n'] = "\\n";
2734
escapes[(int)'\r'] = "\\r";
2835
escapes[(int)'\t'] = "\\t";
36+
escapes[(int)'\x7f'] = "\\u007f"; // U+007F DELETE
2937

3038
initEscapes = true;
3139
}
@@ -38,13 +46,13 @@ static void outputEscape()
3846
"static const char *escapes[256] = {\n");
3947

4048
for (unsigned int i = 0; i < 256; i++) {
41-
if (!escapes[i]) {
49+
if (escapes[i].empty()) {
4250
printf("\tNULL,\n");
4351
} else {
4452
printf("\t\"");
4553

4654
unsigned int si;
47-
for (si = 0; si < strlen(escapes[i]); si++) {
55+
for (si = 0; si < escapes[i].size(); si++) {
4856
char ch = escapes[i][si];
4957
switch (ch) {
5058
case '"':

lib/univalue_escapes.h

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,38 @@
22
#ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H
33
#define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H
44
static const char *escapes[256] = {
5-
NULL,
6-
NULL,
7-
NULL,
8-
NULL,
9-
NULL,
10-
NULL,
11-
NULL,
12-
NULL,
5+
"\\u0000",
6+
"\\u0001",
7+
"\\u0002",
8+
"\\u0003",
9+
"\\u0004",
10+
"\\u0005",
11+
"\\u0006",
12+
"\\u0007",
1313
"\\b",
1414
"\\t",
1515
"\\n",
16-
NULL,
16+
"\\u000b",
1717
"\\f",
1818
"\\r",
19-
NULL,
20-
NULL,
21-
NULL,
22-
NULL,
23-
NULL,
24-
NULL,
25-
NULL,
26-
NULL,
27-
NULL,
28-
NULL,
29-
NULL,
30-
NULL,
31-
NULL,
32-
NULL,
33-
NULL,
34-
NULL,
35-
NULL,
36-
NULL,
19+
"\\u000e",
20+
"\\u000f",
21+
"\\u0010",
22+
"\\u0011",
23+
"\\u0012",
24+
"\\u0013",
25+
"\\u0014",
26+
"\\u0015",
27+
"\\u0016",
28+
"\\u0017",
29+
"\\u0018",
30+
"\\u0019",
31+
"\\u001a",
32+
"\\u001b",
33+
"\\u001c",
34+
"\\u001d",
35+
"\\u001e",
36+
"\\u001f",
3737
NULL,
3838
NULL,
3939
"\\\"",
@@ -129,7 +129,7 @@ static const char *escapes[256] = {
129129
NULL,
130130
NULL,
131131
NULL,
132-
NULL,
132+
"\\u007f",
133133
NULL,
134134
NULL,
135135
NULL,

lib/univalue_write.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ static string json_escape(const string& inS)
2424
if (escStr)
2525
outS += escStr;
2626

27-
else if (isprint(ch))
27+
else if (ch < 0x80)
2828
outS += ch;
2929

30-
else {
30+
else { // TODO handle UTF-8 properly
3131
char tmpesc[16];
3232
sprintf(tmpesc, "\\u%04x", ch);
3333
outS += tmpesc;

test/round1.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
["\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f"]

test/unitester.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,19 @@ static bool test_failed = false;
2323

2424
#define d_assert(expr) { if (!(expr)) { test_failed = true; fprintf(stderr, "%s failed\n", filename.c_str()); } }
2525

26+
static std::string rtrim(std::string s)
27+
{
28+
s.erase(s.find_last_not_of(" \n\r\t")+1);
29+
return s;
30+
}
31+
2632
static void runtest(string filename, const string& jdata)
2733
{
2834
string prefix = filename.substr(0, 4);
2935

30-
bool wantPass = (prefix == "pass");
36+
bool wantPass = (prefix == "pass") || (prefix == "roun");
3137
bool wantFail = (prefix == "fail");
38+
bool wantRoundTrip = (prefix == "roun");
3239
assert(wantPass || wantFail);
3340

3441
UniValue val;
@@ -39,6 +46,11 @@ static void runtest(string filename, const string& jdata)
3946
} else {
4047
d_assert(testResult == false);
4148
}
49+
50+
if (wantRoundTrip) {
51+
std::string odata = val.write(0, 0);
52+
assert(odata == rtrim(jdata));
53+
}
4254
}
4355

4456
static void runtest_file(const char *filename_)
@@ -106,6 +118,7 @@ static const char *filenames[] = {
106118
"pass1.json",
107119
"pass2.json",
108120
"pass3.json",
121+
"round1.json", // round-trip test
109122
};
110123

111124
int main (int argc, char *argv[])

0 commit comments

Comments
 (0)