Skip to content

Commit a9bbb84

Browse files
alejandro-perezsimo5
authored andcommitted
Rework the JSON escaping function.
Cover all the cases mentioned in RFC4627. Reviewed-by: Simo Sorce <simo@redhat.com> Closes #132
1 parent 605ed4d commit a9bbb84

File tree

1 file changed

+47
-21
lines changed

1 file changed

+47
-21
lines changed

src/environ.c

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -101,32 +101,58 @@ static char *mag_escape_display_value(request_rec *req,
101101
gss_buffer_desc disp_value)
102102
{
103103
/* This function returns a copy (in the pool) of the given gss_buffer_t
104-
* where every occurrence of " has been replaced by \". This string is
104+
* where some characters are escaped as required by RFC4627. The string is
105105
* NULL terminated */
106-
int i = 0, j = 0, n_quotes = 0;
106+
char *value = disp_value.value;
107107
char *escaped_value = NULL;
108-
char *value = (char*) disp_value.value;
109-
110-
/* count number of quotes in the input string */
111-
for (i = 0, j = 0; i < disp_value.length; i++)
112-
if (value[i] == '"')
113-
n_quotes++;
114-
115-
/* if there are no quotes, just return a copy of the string */
116-
if (n_quotes == 0)
117-
return apr_pstrndup(req->pool, value, disp_value.length);
118-
119-
/* gss_buffer_t are not \0 terminated, but our result will be */
120-
escaped_value = apr_palloc(req->pool, disp_value.length + n_quotes + 1);
121-
for (i = 0,j = 0; i < disp_value.length; i++, j++) {
122-
if (value[i] == '"') {
123-
escaped_value[j] = '\\';
124-
j++;
108+
char *p = NULL;
109+
110+
/* gss_buffer_t are not \0 terminated, but our result will be. Hence,
111+
* escaped length will be original length * 6 + 1 in the worst case */
112+
p = escaped_value = apr_palloc(req->pool, disp_value.length * 6 + 1);
113+
for (size_t i = 0; i < disp_value.length; i++) {
114+
switch (value[i]) {
115+
case '"':
116+
memcpy(p, "\\\"", 2);
117+
p += 2;
118+
break;
119+
case '\\':
120+
memcpy(p, "\\\\", 2);
121+
p += 2;
122+
break;
123+
case '\b':
124+
memcpy(p, "\\b", 2);
125+
p += 2;
126+
break;
127+
case '\t':
128+
memcpy(p, "\\t", 2);
129+
p += 2;
130+
break;
131+
case '\r':
132+
memcpy(p, "\\r", 2);
133+
p += 2;
134+
break;
135+
case '\f':
136+
memcpy(p, "\\f", 2);
137+
p += 2;
138+
break;
139+
case '\n':
140+
memcpy(p, "\\n", 2);
141+
p += 2;
142+
break;
143+
default:
144+
if (value[i] <= 0x1F) {
145+
apr_snprintf(p, 7, "\\u%04d", (int)value[i]);
146+
p += 6;
147+
} else {
148+
*p = value[i];
149+
p += 1;
150+
}
151+
break;
125152
}
126-
escaped_value[j] = value[i];
127153
}
128154
/* make the string NULL terminated */
129-
escaped_value[j] = '\0';
155+
*p = '\0';
130156
return escaped_value;
131157
}
132158

0 commit comments

Comments
 (0)