Skip to content

Commit 04534b0

Browse files
committed
Merge branch 'PHP-7.1'
2 parents d18741d + 1c733a3 commit 04534b0

File tree

1 file changed

+56
-77
lines changed

1 file changed

+56
-77
lines changed

ext/standard/url.c

Lines changed: 56 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
104104
ue = s + length;
105105

106106
/* parse scheme */
107-
if ((e = memchr(s, ':', length)) && (e - s)) {
107+
if ((e = memchr(s, ':', length)) && e != s) {
108108
/* validate scheme */
109109
p = s;
110110
while (p < e) {
@@ -119,10 +119,10 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
119119
p++;
120120
}
121121

122-
if (*(e + 1) == '\0') { /* only scheme is available */
122+
if (e + 1 == ue) { /* only scheme is available */
123123
ret->scheme = estrndup(s, (e - s));
124124
php_replace_controlchars_ex(ret->scheme, (e - s));
125-
goto end;
125+
return ret;
126126
}
127127

128128
/*
@@ -134,90 +134,91 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
134134
* correctly parse things like a.com:80
135135
*/
136136
p = e + 1;
137-
while (isdigit(*p)) {
137+
while (p < ue && isdigit(*p)) {
138138
p++;
139139
}
140140

141-
if ((*p == '\0' || *p == '/') && (p - e) < 7) {
141+
if ((p == ue || *p == '/') && (p - e) < 7) {
142142
goto parse_port;
143143
}
144144

145145
ret->scheme = estrndup(s, (e-s));
146146
php_replace_controlchars_ex(ret->scheme, (e - s));
147147

148-
length -= ++e - s;
149-
s = e;
148+
s = e + 1;
150149
goto just_path;
151150
} else {
152151
ret->scheme = estrndup(s, (e-s));
153152
php_replace_controlchars_ex(ret->scheme, (e - s));
154153

155-
if (*(e+2) == '/') {
154+
if (e + 2 < ue && *(e + 2) == '/') {
156155
s = e + 3;
157156
if (!strncasecmp("file", ret->scheme, sizeof("file"))) {
158-
if (*(e + 3) == '/') {
157+
if (e + 3 < ue && *(e + 3) == '/') {
159158
/* support windows drive letters as in:
160159
file:///c:/somedir/file.txt
161160
*/
162-
if (*(e + 5) == ':') {
161+
if (e + 5 < ue && *(e + 5) == ':') {
163162
s = e + 4;
164163
}
165-
goto nohost;
164+
goto just_path;
166165
}
167166
}
168167
} else {
169-
if (!strncasecmp("file", ret->scheme, sizeof("file"))) {
170-
s = e + 1;
171-
goto nohost;
172-
} else {
173-
length -= ++e - s;
174-
s = e;
175-
goto just_path;
176-
}
168+
s = e + 1;
169+
goto just_path;
177170
}
178171
}
179172
} else if (e) { /* no scheme; starts with colon: look for port */
180173
parse_port:
181174
p = e + 1;
182175
pp = p;
183176

184-
while (pp-p < 6 && isdigit(*pp)) {
177+
while (pp < ue && pp - p < 6 && isdigit(*pp)) {
185178
pp++;
186179
}
187180

188-
if (pp - p > 0 && pp - p < 6 && (*pp == '/' || *pp == '\0')) {
181+
if (pp - p > 0 && pp - p < 6 && (pp == ue || *pp == '/')) {
189182
zend_long port;
190183
memcpy(port_buf, p, (pp - p));
191184
port_buf[pp - p] = '\0';
192185
port = ZEND_STRTOL(port_buf, NULL, 10);
193186
if (port > 0 && port <= 65535) {
194187
ret->port = (unsigned short) port;
195-
if (*s == '/' && *(s + 1) == '/') { /* relative-scheme URL */
188+
if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */
196189
s += 2;
197190
}
198191
} else {
199192
if (ret->scheme) efree(ret->scheme);
200193
efree(ret);
201194
return NULL;
202195
}
203-
} else if (p == pp && *pp == '\0') {
196+
} else if (p == pp && pp == ue) {
204197
if (ret->scheme) efree(ret->scheme);
205198
efree(ret);
206199
return NULL;
207-
} else if (*s == '/' && *(s + 1) == '/') { /* relative-scheme URL */
200+
} else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */
208201
s += 2;
209202
} else {
210203
goto just_path;
211204
}
212-
} else if (*s == '/' && *(s + 1) == '/') { /* relative-scheme URL */
205+
} else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */
213206
s += 2;
214207
} else {
215-
just_path:
216-
ue = s + length;
217-
goto nohost;
208+
goto just_path;
218209
}
219210

220-
e = s + strcspn(s, "/?#");
211+
/* Binary-safe strcspn(s, "/?#") */
212+
e = ue;
213+
if ((p = memchr(s, '/', e - s))) {
214+
e = p;
215+
}
216+
if ((p = memchr(s, '?', e - s))) {
217+
e = p;
218+
}
219+
if ((p = memchr(s, '#', e - s))) {
220+
e = p;
221+
}
221222

222223
/* check for login and password */
223224
if ((p = zend_memrchr(s, '@', (e-s)))) {
@@ -237,18 +238,16 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
237238
}
238239

239240
/* check for port */
240-
if (*s == '[' && *(e-1) == ']') {
241+
if (s < ue && *s == '[' && *(e-1) == ']') {
241242
/* Short circuit portscan,
242243
we're dealing with an
243244
IPv6 embedded address */
244-
p = s;
245+
p = NULL;
245246
} else {
246-
/* memrchr is a GNU specific extension
247-
Emulate for wide compatibility */
248-
for(p = e; p >= s && *p != ':'; p--);
247+
p = zend_memrchr(s, ':', (e-s));
249248
}
250249

251-
if (p >= s && *p == ':') {
250+
if (p) {
252251
if (!ret->port) {
253252
p++;
254253
if (e-p > 5) { /* port cannot be longer then 5 characters */
@@ -296,54 +295,34 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
296295

297296
s = e;
298297

299-
nohost:
300-
301-
if ((p = memchr(s, '?', (ue - s)))) {
302-
pp = memchr(s, '#', (ue - s));
303-
304-
if (pp && pp < p) {
305-
if (pp - s) {
306-
ret->path = estrndup(s, (pp-s));
307-
php_replace_controlchars_ex(ret->path, (pp - s));
308-
}
309-
p = pp;
310-
goto label_parse;
311-
}
298+
just_path:
312299

313-
if (p - s) {
314-
ret->path = estrndup(s, (p-s));
315-
php_replace_controlchars_ex(ret->path, (p - s));
316-
}
317-
318-
if (pp) {
319-
if (pp - ++p) {
320-
ret->query = estrndup(p, (pp-p));
321-
php_replace_controlchars_ex(ret->query, (pp - p));
322-
}
323-
p = pp;
324-
goto label_parse;
325-
} else if (++p - ue) {
326-
ret->query = estrndup(p, (ue-p));
327-
php_replace_controlchars_ex(ret->query, (ue - p));
328-
}
329-
} else if ((p = memchr(s, '#', (ue - s)))) {
330-
if (p - s) {
331-
ret->path = estrndup(s, (p-s));
332-
php_replace_controlchars_ex(ret->path, (p - s));
300+
e = ue;
301+
p = memchr(s, '#', (e - s));
302+
if (p) {
303+
p++;
304+
if (p < e) {
305+
ret->fragment = estrndup(p, (e - p));
306+
php_replace_controlchars_ex(ret->fragment, (e - p));
333307
}
308+
e = p-1;
309+
}
334310

335-
label_parse:
311+
p = memchr(s, '?', (e - s));
312+
if (p) {
336313
p++;
337-
338-
if (ue - p) {
339-
ret->fragment = estrndup(p, (ue-p));
340-
php_replace_controlchars_ex(ret->fragment, (ue - p));
314+
if (p < e) {
315+
ret->query = estrndup(p, (e - p));
316+
php_replace_controlchars_ex(ret->query, (e - p));
341317
}
342-
} else {
343-
ret->path = estrndup(s, (ue-s));
344-
php_replace_controlchars_ex(ret->path, (ue - s));
318+
e = p-1;
345319
}
346-
end:
320+
321+
if (s < e || s == ue) {
322+
ret->path = estrndup(s, (e - s));
323+
php_replace_controlchars_ex(ret->path, (e - s));
324+
}
325+
347326
return ret;
348327
}
349328
/* }}} */

0 commit comments

Comments
 (0)