Skip to content

Commit f4ec849

Browse files
authored
Merge pull request #40 from open-watt/json_string_escape
Json string writer must escape strings
2 parents 0db535a + e55eafd commit f4ec849

File tree

1 file changed

+68
-6
lines changed

1 file changed

+68
-6
lines changed

src/urt/format/json.d

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,77 @@ ptrdiff_t write_json(ref const Variant val, char[] buffer, bool dense = false, u
104104
if (val.isString)
105105
{
106106
const char[] s = val.asString();
107-
if (buffer.ptr)
107+
108+
if (!buffer.ptr)
108109
{
109-
if (buffer.length < s.length + 2)
110+
size_t len = 0;
111+
foreach (c; s)
112+
{
113+
if (c < 0x20)
114+
{
115+
if (c == '\n' || c == '\r' || c == '\t' || c == '\b' || c == '\f')
116+
len += 2;
117+
else
118+
len += 6;
119+
}
120+
else if (c == '"' || c == '\\')
121+
len += 2;
122+
else
123+
len += 1;
124+
}
125+
return len + 2;
126+
}
127+
128+
if (buffer.length < s.length + 2)
129+
return -1;
130+
131+
buffer[0] = '"';
132+
// escape strings
133+
size_t offset = 1;
134+
foreach (c; s)
135+
{
136+
char sub = void;
137+
if (c < 0x20)
138+
{
139+
if (c == '\n')
140+
sub = 'n';
141+
else if (c == '\r')
142+
sub = 'r';
143+
else if (c == '\t')
144+
sub = 't';
145+
else if (c == '\b')
146+
sub = 'b';
147+
else if (c == '\f')
148+
sub = 'f';
149+
else
150+
{
151+
if (buffer.length < offset + 7)
152+
return -1;
153+
buffer[offset .. offset + 4] = "\\u00";
154+
offset += 4;
155+
buffer[offset++] = hex_digits[c >> 4];
156+
buffer[offset++] = hex_digits[c & 0xF];
157+
continue;
158+
}
159+
}
160+
else if (c == '"' || c == '\\')
161+
sub = c;
162+
else
163+
{
164+
if (buffer.length < offset + 2)
165+
return -1;
166+
buffer[offset++] = c;
167+
continue;
168+
}
169+
170+
// write escape sequence
171+
if (buffer.length < offset + 3)
110172
return -1;
111-
buffer[0] = '"';
112-
buffer[1 .. 1 + s.length] = s[];
113-
buffer[1 + s.length] = '"';
173+
buffer[offset++] = '\\';
174+
buffer[offset++] = sub;
114175
}
115-
return s.length + 2;
176+
buffer[offset++] = '"';
177+
return offset;
116178
}
117179
else
118180
{

0 commit comments

Comments
 (0)