Skip to content

Commit deccf12

Browse files
authored
Sanitize control characters in strings
1 parent d320368 commit deccf12

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

ext/standard/url.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,20 @@ PHPAPI void php_url_free(php_url *theurl)
4747
}
4848
/* }}} */
4949

50+
static void php_replace_controlchars(char *str, size_t len)
51+
{
52+
unsigned char *s = (unsigned char *)str;
53+
unsigned char *e = (unsigned char *)str + len;
54+
55+
ZEND_ASSERT(str != NULL);
56+
57+
while (s < e) {
58+
if (*s <= 0x1F || *s == 0x7F) {
59+
*s = '_';
60+
}
61+
s++;
62+
}
63+
}
5064

5165
PHPAPI php_url *php_url_parse(char const *str)
5266
{
@@ -105,6 +119,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port
105119

106120
if (e + 1 == ue) { /* only scheme is available */
107121
ret->scheme = zend_string_init(s, (e - s), 0);
122+
php_replace_controlchars(ZSTR_VAL(ret->scheme), ZSTR_LEN(ret->scheme));
108123
return ret;
109124
}
110125

@@ -126,11 +141,13 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port
126141
}
127142

128143
ret->scheme = zend_string_init(s, (e-s), 0);
144+
php_replace_controlchars(ZSTR_VAL(ret->scheme), ZSTR_LEN(ret->scheme));
129145

130146
s = e + 1;
131147
goto just_path;
132148
} else {
133149
ret->scheme = zend_string_init(s, (e-s), 0);
150+
php_replace_controlchars(ZSTR_VAL(ret->scheme), ZSTR_LEN(ret->scheme));
134151

135152
if (e + 2 < ue && *(e + 2) == '/') {
136153
s = e + 3;
@@ -196,11 +213,14 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port
196213
if ((p = zend_memrchr(s, '@', (e-s)))) {
197214
if ((pp = memchr(s, ':', (p-s)))) {
198215
ret->user = zend_string_init(s, (pp-s), 0);
216+
php_replace_controlchars(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user));
199217

200218
pp++;
201219
ret->pass = zend_string_init(pp, (p-pp), 0);
220+
php_replace_controlchars(ZSTR_VAL(ret->pass), ZSTR_LEN(ret->pass));
202221
} else {
203222
ret->user = zend_string_init(s, (p-s), 0);
223+
php_replace_controlchars(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user));
204224
}
205225

206226
s = p + 1;
@@ -249,6 +269,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port
249269
}
250270

251271
ret->host = zend_string_init(s, (p-s), 0);
272+
php_replace_controlchars(ZSTR_VAL(ret->host), ZSTR_LEN(ret->host));
252273

253274
if (e == ue) {
254275
return ret;
@@ -264,6 +285,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port
264285
p++;
265286
if (p < e) {
266287
ret->fragment = zend_string_init(p, (e - p), 0);
288+
php_replace_controlchars(ZSTR_VAL(ret->fragment), ZSTR_LEN(ret->fragment));
267289
} else {
268290
ret->fragment = ZSTR_EMPTY_ALLOC();
269291
}
@@ -275,6 +297,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port
275297
p++;
276298
if (p < e) {
277299
ret->query = zend_string_init(p, (e - p), 0);
300+
php_replace_controlchars(ZSTR_VAL(ret->query), ZSTR_LEN(ret->query));
278301
} else {
279302
ret->query = ZSTR_EMPTY_ALLOC();
280303
}
@@ -283,6 +306,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port
283306

284307
if (s < e || s == ue) {
285308
ret->path = zend_string_init(s, (e - s), 0);
309+
php_replace_controlchars(ZSTR_VAL(ret->path), ZSTR_LEN(ret->path));
286310
}
287311

288312
return ret;

0 commit comments

Comments
 (0)