@@ -76,13 +76,46 @@ PHPAPI int php_header(void)
76
76
}
77
77
}
78
78
79
- PHPAPI int php_setcookie (zend_string * name , zend_string * value , time_t expires , zend_string * path , zend_string * domain , int secure , int httponly , zend_string * samesite , int url_encode )
79
+ #define ILLEGAL_COOKIE_CHARACTER "\",\", \";\", \" \", \"\\t\", \"\\r\", \"\\n\", \"\\013\", and \"\\014\""
80
+ PHPAPI int php_setcookie (zend_string * name , zend_string * value , time_t expires , zend_string * path , zend_string * domain ,
81
+ bool secure , bool httponly , zend_string * samesite , bool is_raw )
80
82
{
81
83
zend_string * dt ;
82
84
sapi_header_line ctr = {0 };
83
85
int result ;
84
86
smart_str buf = {0 };
85
87
88
+ if (ZSTR_LEN (name ) == 0 ) {
89
+ zend_argument_value_error (1 , "cannot be empty" );
90
+ return FAILURE ;
91
+ }
92
+ if (strpbrk (ZSTR_VAL (name ), "=,; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
93
+ zend_argument_value_error (1 , "cannot contain \"=\", " ILLEGAL_COOKIE_CHARACTER );
94
+ return FAILURE ;
95
+ }
96
+ if (is_raw && value &&
97
+ strpbrk (ZSTR_VAL (value ), ",; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
98
+ zend_argument_value_error (2 , "cannot contain " ILLEGAL_COOKIE_CHARACTER );
99
+ return FAILURE ;
100
+ }
101
+ /* check to make sure that the year does not exceed 4 digits in length */
102
+ /* Epoch timestamp: 253402300799 corresponds to 31 December 9999 23:59:59 GMT */
103
+ if (expires >= 253402300800 ) {
104
+ zend_value_error ("%s(): \"expire\" option must be less than 253402300800" , get_active_function_name ());
105
+ return FAILURE ;
106
+ }
107
+ if (path && strpbrk (ZSTR_VAL (path ), ",; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
108
+ zend_value_error ("%s(): \"path\" option cannot contain "
109
+ ILLEGAL_COOKIE_CHARACTER , get_active_function_name ());
110
+ return FAILURE ;
111
+ }
112
+ if (domain && strpbrk (ZSTR_VAL (domain ), ",; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
113
+ zend_value_error ("%s(): \"domain\" option cannot contain " ILLEGAL_COOKIE_CHARACTER ,
114
+ get_active_function_name ());
115
+ return FAILURE ;
116
+ }
117
+ /* Should check value of SameSite? */
118
+
86
119
if (value == NULL || ZSTR_LEN (value ) == 0 ) {
87
120
/*
88
121
* MSIE doesn't delete a cookie when you set it to a null value
@@ -100,7 +133,8 @@ PHPAPI int php_setcookie(zend_string *name, zend_string *value, time_t expires,
100
133
smart_str_appends (& buf , "Set-Cookie: " );
101
134
smart_str_append (& buf , name );
102
135
smart_str_appendc (& buf , '=' );
103
- if (url_encode ) {
136
+ /* URL encode when we don't want the raw header */
137
+ if (!is_raw ) {
104
138
zend_string * encoded_value = php_raw_url_encode (ZSTR_VAL (value ), ZSTR_LEN (value ));
105
139
smart_str_append (& buf , encoded_value );
106
140
zend_string_release_ex (encoded_value , 0 );
@@ -113,15 +147,6 @@ PHPAPI int php_setcookie(zend_string *name, zend_string *value, time_t expires,
113
147
114
148
smart_str_appends (& buf , COOKIE_EXPIRES );
115
149
dt = php_format_date ("D, d-M-Y H:i:s T" , sizeof ("D, d-M-Y H:i:s T" )- 1 , expires , 0 );
116
- /* check to make sure that the year does not exceed 4 digits in length */
117
- p = zend_memrchr (ZSTR_VAL (dt ), '-' , ZSTR_LEN (dt ));
118
- if (!p || * (p + 5 ) != ' ' ) {
119
- zend_string_free (dt );
120
- smart_str_free (& buf );
121
- zend_error (E_WARNING , "Expiry date cannot have a year greater than 9999" );
122
- return FAILURE ;
123
- }
124
-
125
150
smart_str_append (& buf , dt );
126
151
zend_string_free (dt );
127
152
@@ -201,7 +226,6 @@ static void php_head_parse_cookie_options_array(zval *options, zend_long *expire
201
226
}
202
227
}
203
228
204
- #define ILLEGAL_COOKIE_CHARACTER "\",\", \";\", \" \", \"\\t\", \"\\r\", \"\\n\", \"\\013\", and \"\\014\""
205
229
static void php_setcookie_common (INTERNAL_FUNCTION_PARAMETERS , bool is_raw )
206
230
{
207
231
/* to handle overloaded function array|int */
@@ -215,6 +239,7 @@ static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw)
215
239
Z_PARAM_OPTIONAL
216
240
Z_PARAM_STR (value )
217
241
Z_PARAM_ZVAL (expires_or_options )
242
+ // Use path ZPP check?
218
243
Z_PARAM_STR (path )
219
244
Z_PARAM_STR (domain )
220
245
Z_PARAM_BOOL (secure )
@@ -229,56 +254,19 @@ static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw)
229
254
RETURN_THROWS ();
230
255
}
231
256
php_head_parse_cookie_options_array (expires_or_options , & expires , & path , & domain , & secure , & httponly , & samesite );
232
- if (path && strpbrk (ZSTR_VAL (path ), ",; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
233
- zend_value_error ("%s(): Argument #3 ($expires_or_options[\"path\"]) cannot contain "
234
- ILLEGAL_COOKIE_CHARACTER , get_active_function_name ());
235
- goto cleanup ;
236
- RETURN_THROWS ();
237
- }
238
- if (domain && strpbrk (ZSTR_VAL (domain ), ",; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
239
- zend_value_error ("%s(): Argument #3 ($expires_or_options[\"domain\"]) cannot contain "
240
- ILLEGAL_COOKIE_CHARACTER , get_active_function_name ());
241
- goto cleanup ;
242
- RETURN_THROWS ();
243
- }
244
- /* Should check value of SameSite? */
245
257
} else {
246
258
expires = zval_get_long (expires_or_options );
247
- if (path && strpbrk (ZSTR_VAL (path ), ",; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
248
- zend_argument_value_error (4 , "cannot contain " ILLEGAL_COOKIE_CHARACTER );
249
- RETURN_THROWS ();
250
- }
251
- if (domain && strpbrk (ZSTR_VAL (domain ), ",; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
252
- zend_argument_value_error (5 , "cannot contain " ILLEGAL_COOKIE_CHARACTER );
253
- RETURN_THROWS ();
254
- }
255
259
}
256
260
}
257
-
258
- if (!ZSTR_LEN (name )) {
259
- zend_argument_value_error (1 , "cannot be empty" );
260
- RETURN_THROWS ();
261
- }
262
- if (strpbrk (ZSTR_VAL (name ), "=,; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
263
- zend_argument_value_error (1 , "cannot contain \"=\", " ILLEGAL_COOKIE_CHARACTER );
264
- RETURN_THROWS ();
265
- }
266
- if (is_raw && value &&
267
- strpbrk (ZSTR_VAL (value ), ",; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
268
- zend_argument_value_error (2 , "cannot contain " ILLEGAL_COOKIE_CHARACTER );
269
- RETURN_THROWS ();
270
- }
271
-
272
261
if (!EG (exception )) {
273
- if (php_setcookie (name , value , expires , path , domain , secure , httponly , samesite , ! is_raw ) == SUCCESS ) {
262
+ if (php_setcookie (name , value , expires , path , domain , secure , httponly , samesite , is_raw ) == SUCCESS ) {
274
263
RETVAL_TRUE ;
275
264
} else {
276
265
RETVAL_FALSE ;
277
266
}
278
267
}
279
268
280
269
if (expires_or_options && Z_TYPE_P (expires_or_options ) == IS_ARRAY ) {
281
- cleanup :
282
270
if (path ) {
283
271
zend_string_release (path );
284
272
}
0 commit comments