@@ -76,36 +76,41 @@ 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\", or \"\\014\""
80
+ PHPAPI zend_result php_setcookie (zend_string * name , zend_string * value , time_t expires ,
81
+ zend_string * path , zend_string * domain , bool secure , bool httponly ,
82
+ zend_string * samesite , bool url_encode )
80
83
{
81
84
zend_string * dt ;
82
85
sapi_header_line ctr = {0 };
83
- int result ;
86
+ zend_result result ;
84
87
smart_str buf = {0 };
85
88
86
89
if (!ZSTR_LEN (name )) {
87
- zend_error ( E_WARNING , "Cookie names must not be empty" );
90
+ zend_argument_value_error ( 1 , "cannot be empty" );
88
91
return FAILURE ;
89
- } else if (strpbrk (ZSTR_VAL (name ), "=,; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
90
- zend_error (E_WARNING , "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" );
92
+ }
93
+ if (strpbrk (ZSTR_VAL (name ), "=,; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
94
+ zend_argument_value_error (1 , "cannot contain \"=\", " ILLEGAL_COOKIE_CHARACTER );
91
95
return FAILURE ;
92
96
}
93
-
94
97
if (!url_encode && value &&
95
98
strpbrk (ZSTR_VAL (value ), ",; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
96
- zend_error ( E_WARNING , "Cookie values cannot contain any of the following ',; \\t\\r\\n\\013\\014'" );
99
+ zend_argument_value_error ( 2 , "cannot contain " ILLEGAL_COOKIE_CHARACTER );
97
100
return FAILURE ;
98
101
}
99
102
100
103
if (path && strpbrk (ZSTR_VAL (path ), ",; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
101
- zend_error (E_WARNING , "Cookie paths cannot contain any of the following ',; \\t\\r\\n\\013\\014'" );
104
+ zend_value_error ("%s(): \"path\" option cannot contain " ILLEGAL_COOKIE_CHARACTER ,
105
+ get_active_function_name ());
102
106
return FAILURE ;
103
107
}
104
-
105
108
if (domain && strpbrk (ZSTR_VAL (domain ), ",; \t\r\n\013\014" ) != NULL ) { /* man isspace for \013 and \014 */
106
- zend_error (E_WARNING , "Cookie domains cannot contain any of the following ',; \\t\\r\\n\\013\\014'" );
109
+ zend_value_error ("%s(): \"domain\" option cannot contain " ILLEGAL_COOKIE_CHARACTER ,
110
+ get_active_function_name ());
107
111
return FAILURE ;
108
112
}
113
+ /* Should check value of SameSite? */
109
114
110
115
if (value == NULL || ZSTR_LEN (value ) == 0 ) {
111
116
/*
@@ -142,7 +147,8 @@ PHPAPI int php_setcookie(zend_string *name, zend_string *value, time_t expires,
142
147
if (!p || * (p + 5 ) != ' ' ) {
143
148
zend_string_free (dt );
144
149
smart_str_free (& buf );
145
- zend_error (E_WARNING , "Expiry date cannot have a year greater than 9999" );
150
+ zend_value_error ("%s(): \"expires\" option cannot have a year greater than 9999" ,
151
+ get_active_function_name ());
146
152
return FAILURE ;
147
153
}
148
154
@@ -186,49 +192,40 @@ PHPAPI int php_setcookie(zend_string *name, zend_string *value, time_t expires,
186
192
return result ;
187
193
}
188
194
189
- static void php_head_parse_cookie_options_array (zval * options , zend_long * expires , zend_string * * path , zend_string * * domain , zend_bool * secure , zend_bool * httponly , zend_string * * samesite ) {
190
- int found = 0 ;
195
+ static zend_result php_head_parse_cookie_options_array (zval * options , zend_long * expires , zend_string * * path ,
196
+ zend_string * * domain , zend_bool * secure , zend_bool * httponly , zend_string * * samesite )
197
+ {
191
198
zend_string * key ;
192
199
zval * value ;
193
200
194
201
ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (options ), key , value ) {
195
- if (key ) {
196
- if (zend_string_equals_literal_ci (key , "expires" )) {
197
- * expires = zval_get_long (value );
198
- found ++ ;
199
- } else if (zend_string_equals_literal_ci (key , "path" )) {
200
- * path = zval_get_string (value );
201
- found ++ ;
202
- } else if (zend_string_equals_literal_ci (key , "domain" )) {
203
- * domain = zval_get_string (value );
204
- found ++ ;
205
- } else if (zend_string_equals_literal_ci (key , "secure" )) {
206
- * secure = zval_is_true (value );
207
- found ++ ;
208
- } else if (zend_string_equals_literal_ci (key , "httponly" )) {
209
- * httponly = zval_is_true (value );
210
- found ++ ;
211
- } else if (zend_string_equals_literal_ci (key , "samesite" )) {
212
- * samesite = zval_get_string (value );
213
- found ++ ;
214
- } else {
215
- php_error_docref (NULL , E_WARNING , "Unrecognized key '%s' found in the options array" , ZSTR_VAL (key ));
216
- }
202
+ if (!key ) {
203
+ zend_value_error ("%s(): option array cannot have numeric keys" , get_active_function_name ());
204
+ return FAILURE ;
205
+ }
206
+ if (zend_string_equals_literal_ci (key , "expires" )) {
207
+ * expires = zval_get_long (value );
208
+ } else if (zend_string_equals_literal_ci (key , "path" )) {
209
+ * path = zval_get_string (value );
210
+ } else if (zend_string_equals_literal_ci (key , "domain" )) {
211
+ * domain = zval_get_string (value );
212
+ } else if (zend_string_equals_literal_ci (key , "secure" )) {
213
+ * secure = zval_is_true (value );
214
+ } else if (zend_string_equals_literal_ci (key , "httponly" )) {
215
+ * httponly = zval_is_true (value );
216
+ } else if (zend_string_equals_literal_ci (key , "samesite" )) {
217
+ * samesite = zval_get_string (value );
217
218
} else {
218
- php_error_docref (NULL , E_WARNING , "Numeric key found in the options array" );
219
+ zend_value_error ("%s(): option \"%s\" is invalid" , get_active_function_name (), ZSTR_VAL (key ));
220
+ return FAILURE ;
219
221
}
220
222
} ZEND_HASH_FOREACH_END ();
221
-
222
- /* Array is not empty but no valid keys were found */
223
- if (found == 0 && zend_hash_num_elements (Z_ARRVAL_P (options )) > 0 ) {
224
- php_error_docref (NULL , E_WARNING , "No valid options were found in the given array" );
225
- }
223
+ return SUCCESS ;
226
224
}
227
225
228
- /* {{{ setcookie(string name [, string value [, array options]])
229
- Send a cookie */
230
- PHP_FUNCTION (setcookie )
226
+ static void php_setcookie_common (INTERNAL_FUNCTION_PARAMETERS , bool is_raw )
231
227
{
228
+ /* to handle overloaded function array|int */
232
229
zval * expires_or_options = NULL ;
233
230
zend_string * name , * value = NULL , * path = NULL , * domain = NULL , * samesite = NULL ;
234
231
zend_long expires = 0 ;
@@ -248,24 +245,27 @@ PHP_FUNCTION(setcookie)
248
245
if (expires_or_options ) {
249
246
if (Z_TYPE_P (expires_or_options ) == IS_ARRAY ) {
250
247
if (UNEXPECTED (ZEND_NUM_ARGS () > 3 )) {
251
- php_error_docref (NULL , E_WARNING , "Cannot pass arguments after the options array" );
252
- RETURN_FALSE ;
248
+ zend_argument_count_error ("%s(): Expects exactly 3 arguments when argument #3 "
249
+ "($expires_or_options) is an array" , get_active_function_name ());
250
+ RETURN_THROWS ();
251
+ }
252
+ if (FAILURE == php_head_parse_cookie_options_array (expires_or_options , & expires , & path ,
253
+ & domain , & secure , & httponly , & samesite )) {
254
+ goto cleanup ;
253
255
}
254
- php_head_parse_cookie_options_array (expires_or_options , & expires , & path , & domain , & secure , & httponly , & samesite );
255
256
} else {
256
257
expires = zval_get_long (expires_or_options );
257
258
}
258
259
}
259
260
260
- if (!EG (exception )) {
261
- if (php_setcookie (name , value , expires , path , domain , secure , httponly , samesite , 1 ) == SUCCESS ) {
262
- RETVAL_TRUE ;
263
- } else {
264
- RETVAL_FALSE ;
265
- }
261
+ if (php_setcookie (name , value , expires , path , domain , secure , httponly , samesite , !is_raw ) == SUCCESS ) {
262
+ RETVAL_TRUE ;
263
+ } else {
264
+ RETVAL_FALSE ;
266
265
}
267
266
268
267
if (expires_or_options && Z_TYPE_P (expires_or_options ) == IS_ARRAY ) {
268
+ cleanup :
269
269
if (path ) {
270
270
zend_string_release (path );
271
271
}
@@ -277,59 +277,20 @@ PHP_FUNCTION(setcookie)
277
277
}
278
278
}
279
279
}
280
+
281
+ /* {{{ setcookie(string name [, string value [, array options]])
282
+ Send a cookie */
283
+ PHP_FUNCTION (setcookie )
284
+ {
285
+ php_setcookie_common (INTERNAL_FUNCTION_PARAM_PASSTHRU , false);
286
+ }
280
287
/* }}} */
281
288
282
289
/* {{{ setrawcookie(string name [, string value [, array options]])
283
290
Send a cookie with no url encoding of the value */
284
291
PHP_FUNCTION (setrawcookie )
285
292
{
286
- zval * expires_or_options = NULL ;
287
- zend_string * name , * value = NULL , * path = NULL , * domain = NULL , * samesite = NULL ;
288
- zend_long expires = 0 ;
289
- zend_bool secure = 0 , httponly = 0 ;
290
-
291
- ZEND_PARSE_PARAMETERS_START (1 , 7 )
292
- Z_PARAM_STR (name )
293
- Z_PARAM_OPTIONAL
294
- Z_PARAM_STR (value )
295
- Z_PARAM_ZVAL (expires_or_options )
296
- Z_PARAM_STR (path )
297
- Z_PARAM_STR (domain )
298
- Z_PARAM_BOOL (secure )
299
- Z_PARAM_BOOL (httponly )
300
- ZEND_PARSE_PARAMETERS_END ();
301
-
302
- if (expires_or_options ) {
303
- if (Z_TYPE_P (expires_or_options ) == IS_ARRAY ) {
304
- if (UNEXPECTED (ZEND_NUM_ARGS () > 3 )) {
305
- php_error_docref (NULL , E_WARNING , "Cannot pass arguments after the options array" );
306
- RETURN_FALSE ;
307
- }
308
- php_head_parse_cookie_options_array (expires_or_options , & expires , & path , & domain , & secure , & httponly , & samesite );
309
- } else {
310
- expires = zval_get_long (expires_or_options );
311
- }
312
- }
313
-
314
- if (!EG (exception )) {
315
- if (php_setcookie (name , value , expires , path , domain , secure , httponly , samesite , 0 ) == SUCCESS ) {
316
- RETVAL_TRUE ;
317
- } else {
318
- RETVAL_FALSE ;
319
- }
320
- }
321
-
322
- if (expires_or_options && Z_TYPE_P (expires_or_options ) == IS_ARRAY ) {
323
- if (path ) {
324
- zend_string_release (path );
325
- }
326
- if (domain ) {
327
- zend_string_release (domain );
328
- }
329
- if (samesite ) {
330
- zend_string_release (samesite );
331
- }
332
- }
293
+ php_setcookie_common (INTERNAL_FUNCTION_PARAM_PASSTHRU , true);
333
294
}
334
295
/* }}} */
335
296
0 commit comments