Skip to content

Commit 79376ab

Browse files
kachalinalexeycmb69
authored andcommitted
Fix #78929: plus signs in cookie values are converted to spaces
We switch the cookie value parsing function from `php_url_decode()` to `php_raw_url_decode()`, so that cookie values are now parsed according to RFC 6265, section 4.1.1. We also refactor to remove duplicate code without changing the execution flow.
1 parent be89a5c commit 79376ab

File tree

3 files changed

+37
-18
lines changed

3 files changed

+37
-18
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ PHP NEWS
33

44
?? ??? ????, PHP 7.4.2
55

6+
- Core:
7+
. Fixed bug #78929 (plus signs in cookie values are converted to spaces).
8+
(Alexey Kachalin)
9+
610
- OPcache:
711
. Fixed bug #78950 (Preloading trait method with static variables). (Nikita)
812

main/php_variables.c

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,9 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
479479
var = php_strtok_r(res, separator, &strtok_buf);
480480

481481
while (var) {
482+
size_t val_len;
483+
size_t new_val_len;
484+
482485
val = strchr(var, '=');
483486

484487
if (arg == PARSE_COOKIE) {
@@ -497,29 +500,25 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
497500
}
498501

499502
if (val) { /* have a value */
500-
size_t val_len;
501-
size_t new_val_len;
502503

503504
*val++ = '\0';
504-
php_url_decode(var, strlen(var));
505-
val_len = php_url_decode(val, strlen(val));
506-
val = estrndup(val, val_len);
507-
if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) {
508-
php_register_variable_safe(var, val, new_val_len, &array);
505+
506+
if (arg == PARSE_COOKIE) {
507+
val_len = php_raw_url_decode(val, strlen(val));
508+
} else {
509+
val_len = php_url_decode(val, strlen(val));
509510
}
510-
efree(val);
511511
} else {
512-
size_t val_len;
513-
size_t new_val_len;
514-
515-
php_url_decode(var, strlen(var));
516-
val_len = 0;
517-
val = estrndup("", val_len);
518-
if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) {
519-
php_register_variable_safe(var, val, new_val_len, &array);
520-
}
521-
efree(val);
512+
val = "";
513+
val_len = 0;
514+
}
515+
516+
val = estrndup(val, val_len);
517+
php_url_decode(var, strlen(var));
518+
if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) {
519+
php_register_variable_safe(var, val, new_val_len, &array);
522520
}
521+
efree(val);
523522
next_cookie:
524523
var = php_strtok_r(NULL, separator, &strtok_buf);
525524
}

tests/basic/bug78929.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Bug #78929 (plus signs in cookie values are converted to spaces)
3+
--INI--
4+
max_input_vars=1000
5+
filter.default=unsafe_raw
6+
--COOKIE--
7+
RFC6265=#$%&'()*+-./0123456789<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~!
8+
--FILE--
9+
<?php
10+
var_dump($_COOKIE);
11+
?>
12+
--EXPECT--
13+
array(1) {
14+
["RFC6265"]=>
15+
string(89) "#$%&'()*+-./0123456789<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~!"
16+
}

0 commit comments

Comments
 (0)