@@ -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,28 +133,19 @@ 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 );
107
141
} else {
108
142
smart_str_append (& buf , value );
109
143
}
110
144
if (expires > 0 ) {
111
- const char * p ;
112
145
double diff ;
113
146
114
147
smart_str_appends (& buf , COOKIE_EXPIRES );
115
148
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
149
smart_str_append (& buf , dt );
126
150
zend_string_free (dt );
127
151
@@ -201,7 +225,6 @@ static void php_head_parse_cookie_options_array(zval *options, zend_long *expire
201
225
}
202
226
}
203
227
204
- #define ILLEGAL_COOKIE_CHARACTER "\",\", \";\", \" \", \"\\t\", \"\\r\", \"\\n\", \"\\013\", and \"\\014\""
205
228
static void php_setcookie_common (INTERNAL_FUNCTION_PARAMETERS , bool is_raw )
206
229
{
207
230
/* to handle overloaded function array|int */
@@ -215,6 +238,7 @@ static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw)
215
238
Z_PARAM_OPTIONAL
216
239
Z_PARAM_STR (value )
217
240
Z_PARAM_ZVAL (expires_or_options )
241
+ // Use path ZPP check?
218
242
Z_PARAM_STR (path )
219
243
Z_PARAM_STR (domain )
220
244
Z_PARAM_BOOL (secure )
@@ -229,56 +253,19 @@ static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw)
229
253
RETURN_THROWS ();
230
254
}
231
255
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
256
} else {
246
257
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
258
}
256
259
}
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
260
if (!EG (exception )) {
273
- if (php_setcookie (name , value , expires , path , domain , secure , httponly , samesite , ! is_raw ) == SUCCESS ) {
261
+ if (php_setcookie (name , value , expires , path , domain , secure , httponly , samesite , is_raw ) == SUCCESS ) {
274
262
RETVAL_TRUE ;
275
263
} else {
276
264
RETVAL_FALSE ;
277
265
}
278
266
}
279
267
280
268
if (expires_or_options && Z_TYPE_P (expires_or_options ) == IS_ARRAY ) {
281
- cleanup :
282
269
if (path ) {
283
270
zend_string_release (path );
284
271
}
0 commit comments