mirror of
https://github.com/php/php-src.git
synced 2026-03-24 08:12:21 +01:00
Support for samesite cookies with array syntax
Allows using an alternative array argument with support for the samesite option on the following functions: setcookie setrawcookie session_set_cookie_params
This commit is contained in:
committed by
Christoph M. Becker
parent
08b9310e6d
commit
2b58ab23c6
@@ -1664,21 +1664,31 @@ PHPAPI void session_adapt_url(const char *url, size_t urllen, char **new, size_t
|
||||
* Userspace exported functions *
|
||||
******************************** */
|
||||
|
||||
/* {{{ proto void session_set_cookie_params(int lifetime [, string path [, string domain [, bool secure[, bool httponly[, string samesite]]]]])
|
||||
/* {{{ proto bool session_set_cookie_params(int lifetime [, string path [, string domain [, bool secure[, bool httponly]]]])
|
||||
session_set_cookie_params(array options)
|
||||
Set session cookie parameters */
|
||||
static PHP_FUNCTION(session_set_cookie_params)
|
||||
{
|
||||
zval *lifetime;
|
||||
zend_string *path = NULL, *domain = NULL, *samesite = NULL;
|
||||
int argc = ZEND_NUM_ARGS();
|
||||
zend_bool secure = 0, httponly = 0;
|
||||
zval *lifetime_or_options = NULL;
|
||||
zend_string *lifetime = NULL, *path = NULL, *domain = NULL, *samesite = NULL;
|
||||
zend_bool secure = 0, secure_null = 1;
|
||||
zend_bool httponly = 0, httponly_null = 1;
|
||||
zend_string *ini_name;
|
||||
int result;
|
||||
int found = 0;
|
||||
|
||||
if (!PS(use_cookies) ||
|
||||
zend_parse_parameters(argc, "z|SSbbS", &lifetime, &path, &domain, &secure, &httponly, &samesite) == FAILURE) {
|
||||
if (!PS(use_cookies)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 5)
|
||||
Z_PARAM_ZVAL(lifetime_or_options)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_STR(path)
|
||||
Z_PARAM_STR(domain)
|
||||
Z_PARAM_BOOL_EX(secure, secure_null, 1, 0)
|
||||
Z_PARAM_BOOL_EX(httponly, httponly_null, 1, 0)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (PS(session_status) == php_session_active) {
|
||||
php_error_docref(NULL, E_WARNING, "Cannot change session cookie parameters when session is active");
|
||||
@@ -1690,54 +1700,107 @@ static PHP_FUNCTION(session_set_cookie_params)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
convert_to_string_ex(lifetime);
|
||||
if (Z_TYPE_P(lifetime_or_options) == IS_ARRAY) {
|
||||
zend_string *key;
|
||||
zval *value;
|
||||
|
||||
ini_name = zend_string_init("session.cookie_lifetime", sizeof("session.cookie_lifetime") - 1, 0);
|
||||
if (zend_alter_ini_entry(ini_name, Z_STR_P(lifetime), PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == FAILURE) {
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(lifetime_or_options), key, value) {
|
||||
if (key) {
|
||||
ZVAL_DEREF(value);
|
||||
if(!strcasecmp("lifetime", ZSTR_VAL(key))) {
|
||||
lifetime = zval_get_string(value);
|
||||
found++;
|
||||
} else if(!strcasecmp("path", ZSTR_VAL(key))) {
|
||||
path = zval_get_string(value);
|
||||
found++;
|
||||
} else if(!strcasecmp("domain", ZSTR_VAL(key))) {
|
||||
domain = zval_get_string(value);
|
||||
found++;
|
||||
} else if(!strcasecmp("secure", ZSTR_VAL(key))) {
|
||||
secure = zval_is_true(value);
|
||||
secure_null = 0;
|
||||
found++;
|
||||
} else if(!strcasecmp("httponly", ZSTR_VAL(key))) {
|
||||
httponly = zval_is_true(value);
|
||||
httponly_null = 0;
|
||||
found++;
|
||||
} else if(!strcasecmp("samesite", ZSTR_VAL(key))) {
|
||||
samesite = zval_get_string(value);
|
||||
found++;
|
||||
} else {
|
||||
php_error_docref(NULL, E_WARNING, "Unrecognized key '%s' found in the options array", ZSTR_VAL(key));
|
||||
}
|
||||
} else {
|
||||
php_error_docref(NULL, E_WARNING, "Numeric key found in the options array");
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (path) {
|
||||
ini_name = zend_string_init("session.cookie_path", sizeof("session.cookie_path") - 1, 0);
|
||||
if (zend_alter_ini_entry(ini_name, path, PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == FAILURE) {
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
if (found == 0) {
|
||||
php_error_docref(NULL, E_WARNING, "No valid keys were found in the options array");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
} else {
|
||||
lifetime = zval_get_string(lifetime_or_options);
|
||||
}
|
||||
|
||||
if (lifetime) {
|
||||
ini_name = zend_string_init("session.cookie_lifetime", sizeof("session.cookie_lifetime") - 1, 0);
|
||||
result = zend_alter_ini_entry(ini_name, lifetime, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
|
||||
zend_string_release(lifetime);
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
if (result == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
if (path) {
|
||||
ini_name = zend_string_init("session.cookie_path", sizeof("session.cookie_path") - 1, 0);
|
||||
result = zend_alter_ini_entry(ini_name, path, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
|
||||
if (found > 0) {
|
||||
zend_string_release(path);
|
||||
}
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
if (result == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
if (domain) {
|
||||
ini_name = zend_string_init("session.cookie_domain", sizeof("session.cookie_domain") - 1, 0);
|
||||
if (zend_alter_ini_entry(ini_name, domain, PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == FAILURE) {
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
RETURN_FALSE;
|
||||
result = zend_alter_ini_entry(ini_name, domain, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
|
||||
if (found > 0) {
|
||||
zend_string_release(domain);
|
||||
}
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
if (result == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
if (!secure_null) {
|
||||
ini_name = zend_string_init("session.cookie_secure", sizeof("session.cookie_secure") - 1, 0);
|
||||
if (zend_alter_ini_entry_chars(ini_name, secure ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == FAILURE) {
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
result = zend_alter_ini_entry_chars(ini_name, secure ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
if (result == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
}
|
||||
if (argc > 4) {
|
||||
if (!httponly_null) {
|
||||
ini_name = zend_string_init("session.cookie_httponly", sizeof("session.cookie_httponly") - 1, 0);
|
||||
if (zend_alter_ini_entry_chars(ini_name, httponly ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == FAILURE) {
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
result = zend_alter_ini_entry_chars(ini_name, httponly ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
if (result == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
if (samesite) {
|
||||
ini_name = zend_string_init("session.cookie_samesite", sizeof("session.cookie_samesite") - 1, 0);
|
||||
result = zend_alter_ini_entry(ini_name, samesite, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
|
||||
if (found > 0) {
|
||||
zend_string_release(samesite);
|
||||
}
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
if (result == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
}
|
||||
|
||||
if (argc > 5) {
|
||||
ini_name = zend_string_init("session.cookie_samesite", sizeof("session.cookie_samesite") - 1, 0);
|
||||
zend_alter_ini_entry(ini_name, samesite, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
|
||||
zend_string_release(ini_name);
|
||||
}
|
||||
|
||||
RETURN_TRUE;
|
||||
}
|
||||
@@ -2638,12 +2701,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_session_cache_expire, 0, 0, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_session_set_cookie_params, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, lifetime)
|
||||
ZEND_ARG_INFO(0, lifetime_or_options)
|
||||
ZEND_ARG_INFO(0, path)
|
||||
ZEND_ARG_INFO(0, domain)
|
||||
ZEND_ARG_INFO(0, secure)
|
||||
ZEND_ARG_INFO(0, httponly)
|
||||
ZEND_ARG_INFO(0, samesite)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_session_class_open, 0)
|
||||
|
||||
@@ -23,9 +23,17 @@ ob_start();
|
||||
echo "*** Testing session_get_cookie_params() : basic functionality ***\n";
|
||||
|
||||
var_dump(session_get_cookie_params());
|
||||
var_dump(session_set_cookie_params(3600, "/path", "blah", FALSE, FALSE, "foo"));
|
||||
var_dump(session_set_cookie_params(3600, "/path", "blah", FALSE, FALSE));
|
||||
var_dump(session_get_cookie_params());
|
||||
var_dump(session_set_cookie_params(1234567890, "/guff", "foo", TRUE, TRUE, "blah"));
|
||||
var_dump(session_set_cookie_params(1234567890, "/guff", "foo", TRUE, TRUE));
|
||||
var_dump(session_get_cookie_params());
|
||||
var_dump(session_set_cookie_params([
|
||||
"lifetime" => 123,
|
||||
"path" => "/bar",
|
||||
"domain" => "baz",
|
||||
"secure" => FALSE,
|
||||
"httponly" => FALSE,
|
||||
"samesite" => "please"]));
|
||||
var_dump(session_get_cookie_params());
|
||||
|
||||
echo "Done";
|
||||
@@ -60,7 +68,7 @@ array(6) {
|
||||
["httponly"]=>
|
||||
bool(false)
|
||||
["samesite"]=>
|
||||
string(3) "foo"
|
||||
string(0) ""
|
||||
}
|
||||
bool(true)
|
||||
array(6) {
|
||||
@@ -75,6 +83,21 @@ array(6) {
|
||||
["httponly"]=>
|
||||
bool(true)
|
||||
["samesite"]=>
|
||||
string(4) "blah"
|
||||
string(0) ""
|
||||
}
|
||||
bool(true)
|
||||
array(6) {
|
||||
["lifetime"]=>
|
||||
int(123)
|
||||
["path"]=>
|
||||
string(4) "/bar"
|
||||
["domain"]=>
|
||||
string(3) "baz"
|
||||
["secure"]=>
|
||||
bool(false)
|
||||
["httponly"]=>
|
||||
bool(false)
|
||||
["samesite"]=>
|
||||
string(6) "please"
|
||||
}
|
||||
Done
|
||||
|
||||
@@ -10,7 +10,7 @@ session.cookie_domain=foo
|
||||
ob_start();
|
||||
|
||||
/*
|
||||
* Prototype : void session_set_cookie_params(int $lifetime [, string $path [, string $domain [, bool $secure [, bool $httponly[, string $samesite]]]]])
|
||||
* Prototype : void session_set_cookie_params(int $lifetime [, string $path [, string $domain [, bool $secure [, bool $httponly]]]])
|
||||
* Description : Set the session cookie parameters
|
||||
* Source code : ext/session/session.c
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,7 @@ session.cookie_httponly=TRUE
|
||||
ob_start();
|
||||
|
||||
/*
|
||||
* Prototype : void session_set_cookie_params(int $lifetime [, string $path [, string $domain [, bool $secure [, bool $httponly[, string $samesite]]]]])
|
||||
* Prototype : void session_set_cookie_params(int $lifetime [, string $path [, string $domain [, bool $secure [, bool $httponly]]]])
|
||||
* Description : Set the session cookie parameters
|
||||
* Source code : ext/session/session.c
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,7 @@ session.cookie_samesite=test
|
||||
ob_start();
|
||||
|
||||
/*
|
||||
* Prototype : void session_set_cookie_params(int $lifetime [, string $path [, string $domain [, bool $secure [, bool $samesite[, string $samesite]]]]])
|
||||
* Prototype : void session_set_cookie_params(array $options)
|
||||
* Description : Set the session cookie parameters
|
||||
* Source code : ext/session/session.c
|
||||
*/
|
||||
@@ -18,15 +18,15 @@ ob_start();
|
||||
echo "*** Testing session_set_cookie_params() : variation ***\n";
|
||||
|
||||
var_dump(ini_get("session.cookie_samesite"));
|
||||
var_dump(session_set_cookie_params(3600, "/path", "blah", FALSE, FALSE, "nothing"));
|
||||
var_dump(session_set_cookie_params(["samesite" => "nothing"]));
|
||||
var_dump(ini_get("session.cookie_samesite"));
|
||||
var_dump(session_start());
|
||||
var_dump(ini_get("session.cookie_samesite"));
|
||||
var_dump(session_set_cookie_params(3600, "/path", "blah", FALSE, TRUE, "test"));
|
||||
var_dump(session_set_cookie_params(["samesite" => "test"]));
|
||||
var_dump(ini_get("session.cookie_samesite"));
|
||||
var_dump(session_destroy());
|
||||
var_dump(ini_get("session.cookie_samesite"));
|
||||
var_dump(session_set_cookie_params(3600, "/path", "blah", FALSE, FALSE, "other"));
|
||||
var_dump(session_set_cookie_params(["samesite" => "other"]));
|
||||
var_dump(ini_get("session.cookie_samesite"));
|
||||
|
||||
echo "Done";
|
||||
|
||||
60
ext/session/tests/session_set_cookie_params_variation7.phpt
Normal file
60
ext/session/tests/session_set_cookie_params_variation7.phpt
Normal file
@@ -0,0 +1,60 @@
|
||||
--TEST--
|
||||
Test session_set_cookie_params() function : array parameter variation
|
||||
--INI--
|
||||
session.cookie_lifetime=0
|
||||
session.cookie_path="/"
|
||||
session.cookie_domain=""
|
||||
session.cookie_secure=0
|
||||
session.cookie_httponly=0
|
||||
session.cookie_samesite=""
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ob_start();
|
||||
|
||||
/*
|
||||
* Prototype : void session_set_cookie_params(array $options)
|
||||
* Description : Set the session cookie parameters
|
||||
* Source code : ext/session/session.c
|
||||
*/
|
||||
|
||||
echo "*** Testing session_set_cookie_params() : array parameter variation ***\n";
|
||||
|
||||
// Invalid cases
|
||||
var_dump(session_set_cookie_params([]));
|
||||
var_dump(session_set_cookie_params(["unknown_key" => true]));
|
||||
|
||||
var_dump(ini_get("session.cookie_secure"));
|
||||
var_dump(ini_get("session.cookie_samesite"));
|
||||
var_dump(session_set_cookie_params(["secure" => true, "samesite" => "please"]));
|
||||
var_dump(ini_get("session.cookie_secure"));
|
||||
var_dump(ini_get("session.cookie_samesite"));
|
||||
|
||||
var_dump(ini_get("session.cookie_lifetime"));
|
||||
var_dump(session_set_cookie_params(["lifetime" => 42]));
|
||||
var_dump(ini_get("session.cookie_lifetime"));
|
||||
|
||||
echo "Done";
|
||||
ob_end_flush();
|
||||
?>
|
||||
--EXPECTF--
|
||||
*** Testing session_set_cookie_params() : array parameter variation ***
|
||||
|
||||
Warning: session_set_cookie_params(): No valid keys were found in the options array in %s
|
||||
bool(false)
|
||||
|
||||
Warning: session_set_cookie_params(): Unrecognized key 'unknown_key' found in the options array in %s
|
||||
|
||||
Warning: session_set_cookie_params(): No valid keys were found in the options array in %s
|
||||
bool(false)
|
||||
string(1) "0"
|
||||
string(0) ""
|
||||
bool(true)
|
||||
string(1) "1"
|
||||
string(6) "please"
|
||||
string(1) "0"
|
||||
bool(true)
|
||||
string(2) "42"
|
||||
Done
|
||||
@@ -1431,23 +1431,21 @@ ZEND_END_ARG_INFO()
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_setcookie, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, name)
|
||||
ZEND_ARG_INFO(0, value)
|
||||
ZEND_ARG_INFO(0, expires)
|
||||
ZEND_ARG_INFO(0, expires_or_options)
|
||||
ZEND_ARG_INFO(0, path)
|
||||
ZEND_ARG_INFO(0, domain)
|
||||
ZEND_ARG_INFO(0, secure)
|
||||
ZEND_ARG_INFO(0, httponly)
|
||||
ZEND_ARG_INFO(0, samesite)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_setrawcookie, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, name)
|
||||
ZEND_ARG_INFO(0, value)
|
||||
ZEND_ARG_INFO(0, expires)
|
||||
ZEND_ARG_INFO(0, expires_or_options)
|
||||
ZEND_ARG_INFO(0, path)
|
||||
ZEND_ARG_INFO(0, domain)
|
||||
ZEND_ARG_INFO(0, secure)
|
||||
ZEND_ARG_INFO(0, httponly)
|
||||
ZEND_ARG_INFO(0, samesite)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_headers_sent, 0, 0, 0)
|
||||
|
||||
@@ -79,7 +79,7 @@ PHPAPI int php_header(void)
|
||||
}
|
||||
}
|
||||
|
||||
PHPAPI int php_setcookie(zend_string *name, zend_string *value, time_t expires, zend_string *path, zend_string *domain, int secure, int url_encode, int httponly, zend_string *samesite)
|
||||
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)
|
||||
{
|
||||
char *cookie;
|
||||
size_t len = sizeof("Set-Cookie: ");
|
||||
@@ -206,61 +206,154 @@ PHPAPI int php_setcookie(zend_string *name, zend_string *value, time_t expires,
|
||||
return result;
|
||||
}
|
||||
|
||||
static int 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) {
|
||||
int found = 0;
|
||||
zend_string *key;
|
||||
zval *value;
|
||||
|
||||
/* php_set_cookie(name, value, expires, path, domain, secure) */
|
||||
/* {{{ proto bool setcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly[, string samesite]]]]]]])
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), key, value) {
|
||||
if (key) {
|
||||
ZVAL_DEREF(value);
|
||||
if(!strcasecmp("expires", ZSTR_VAL(key))) {
|
||||
*expires = zval_get_long(value);
|
||||
found++;
|
||||
} else if(!strcasecmp("path", ZSTR_VAL(key))) {
|
||||
*path = zval_get_string(value);
|
||||
found++;
|
||||
} else if(!strcasecmp("domain", ZSTR_VAL(key))) {
|
||||
*domain = zval_get_string(value);
|
||||
found++;
|
||||
} else if(!strcasecmp("secure", ZSTR_VAL(key))) {
|
||||
*secure = zval_is_true(value);
|
||||
found++;
|
||||
} else if(!strcasecmp("httponly", ZSTR_VAL(key))) {
|
||||
*httponly = zval_is_true(value);
|
||||
found++;
|
||||
} else if(!strcasecmp("samesite", ZSTR_VAL(key))) {
|
||||
*samesite = zval_get_string(value);
|
||||
found++;
|
||||
} else {
|
||||
php_error_docref(NULL, E_WARNING, "Unrecognized key '%s' found in the options array", ZSTR_VAL(key));
|
||||
}
|
||||
} else {
|
||||
php_error_docref(NULL, E_WARNING, "Numeric key found in the options array");
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
/* Array is not empty but no valid keys were found */
|
||||
if (found == 0 && zend_hash_num_elements(Z_ARRVAL_P(options)) > 0) {
|
||||
php_error_docref(NULL, E_WARNING, "No valid options were found in the given array");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* {{{ proto bool setcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])
|
||||
setcookie(string name [, string value [, array options]])
|
||||
Send a cookie */
|
||||
PHP_FUNCTION(setcookie)
|
||||
{
|
||||
zval *expires_or_options = NULL;
|
||||
zend_string *name, *value = NULL, *path = NULL, *domain = NULL, *samesite = NULL;
|
||||
zend_long expires = 0;
|
||||
zend_bool secure = 0, httponly = 0;
|
||||
zend_bool secure = 0, httponly = 0, options_array = 0;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 8)
|
||||
ZEND_PARSE_PARAMETERS_START(1, 7)
|
||||
Z_PARAM_STR(name)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_STR(value)
|
||||
Z_PARAM_LONG(expires)
|
||||
Z_PARAM_ZVAL(expires_or_options)
|
||||
Z_PARAM_STR(path)
|
||||
Z_PARAM_STR(domain)
|
||||
Z_PARAM_BOOL(secure)
|
||||
Z_PARAM_BOOL(httponly)
|
||||
Z_PARAM_STR(samesite)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (php_setcookie(name, value, expires, path, domain, secure, 1, httponly, samesite) == SUCCESS) {
|
||||
if (expires_or_options) {
|
||||
if (Z_TYPE_P(expires_or_options) == IS_ARRAY) {
|
||||
options_array = 1;
|
||||
if (!php_head_parse_cookie_options_array(expires_or_options, &expires, &path, &domain, &secure, &httponly, &samesite)) {
|
||||
RETVAL_FALSE;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
expires = Z_LVAL_P(expires_or_options);
|
||||
}
|
||||
}
|
||||
|
||||
if (php_setcookie(name, value, expires, path, domain, secure, httponly, samesite, 1) == SUCCESS) {
|
||||
RETVAL_TRUE;
|
||||
} else {
|
||||
RETVAL_FALSE;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (options_array) {
|
||||
if (path) {
|
||||
zend_string_release(path);
|
||||
}
|
||||
if (domain) {
|
||||
zend_string_release(domain);
|
||||
}
|
||||
if (samesite) {
|
||||
zend_string_release(samesite);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool setrawcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly[, string samesite]]]]]]])
|
||||
/* {{{ proto bool setrawcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])
|
||||
setrawcookie(string name [, string value [, array options]])
|
||||
Send a cookie with no url encoding of the value */
|
||||
PHP_FUNCTION(setrawcookie)
|
||||
{
|
||||
zval *expires_or_options = NULL;
|
||||
zend_string *name, *value = NULL, *path = NULL, *domain = NULL, *samesite = NULL;
|
||||
zend_long expires = 0;
|
||||
zend_bool secure = 0, httponly = 0;
|
||||
zend_bool secure = 0, httponly = 0, options_array = 0;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 8)
|
||||
ZEND_PARSE_PARAMETERS_START(1, 7)
|
||||
Z_PARAM_STR(name)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_STR(value)
|
||||
Z_PARAM_LONG(expires)
|
||||
Z_PARAM_ZVAL(expires_or_options)
|
||||
Z_PARAM_STR(path)
|
||||
Z_PARAM_STR(domain)
|
||||
Z_PARAM_BOOL(secure)
|
||||
Z_PARAM_BOOL(httponly)
|
||||
Z_PARAM_STR(samesite)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (php_setcookie(name, value, expires, path, domain, secure, 0, httponly, samesite) == SUCCESS) {
|
||||
if (expires_or_options) {
|
||||
if (Z_TYPE_P(expires_or_options) == IS_ARRAY) {
|
||||
options_array = 1;
|
||||
if (!php_head_parse_cookie_options_array(expires_or_options, &expires, &path, &domain, &secure, &httponly, &samesite)) {
|
||||
RETVAL_FALSE;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
expires = Z_LVAL_P(expires_or_options);
|
||||
}
|
||||
}
|
||||
|
||||
if (php_setcookie(name, value, expires, path, domain, secure, httponly, samesite, 0) == SUCCESS) {
|
||||
RETVAL_TRUE;
|
||||
} else {
|
||||
RETVAL_FALSE;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (options_array) {
|
||||
if (path) {
|
||||
zend_string_release(path);
|
||||
}
|
||||
if (domain) {
|
||||
zend_string_release(domain);
|
||||
}
|
||||
if (samesite) {
|
||||
zend_string_release(samesite);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -37,6 +37,6 @@ PHP_FUNCTION(headers_list);
|
||||
PHP_FUNCTION(http_response_code);
|
||||
|
||||
PHPAPI int php_header(void);
|
||||
PHPAPI int php_setcookie(zend_string *name, zend_string *value, time_t expires, zend_string *path, zend_string *domain, int secure, int url_encode, int httponly, zend_string *samesite);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,8 @@ setcookie('name', 'value', 0, '', 'domain.tld');
|
||||
setcookie('name', 'value', 0, '', '', TRUE);
|
||||
setcookie('name', 'value', 0, '', '', FALSE, TRUE);
|
||||
|
||||
setcookie('name', 'value', ['expires' => $tsp]);
|
||||
setcookie('name', 'value', ['expires' => $tsn, 'path' => '/path/', 'domain' => 'domain.tld', 'secure' => true, 'httponly' => true, 'samesite' => 'Strict']);
|
||||
|
||||
$expected = array(
|
||||
'Set-Cookie: name=deleted; expires='.date('D, d-M-Y H:i:s', 1).' GMT; Max-Age=0',
|
||||
@@ -30,7 +32,9 @@ $expected = array(
|
||||
'Set-Cookie: name=value; path=/path/',
|
||||
'Set-Cookie: name=value; domain=domain.tld',
|
||||
'Set-Cookie: name=value; secure',
|
||||
'Set-Cookie: name=value; HttpOnly'
|
||||
'Set-Cookie: name=value; HttpOnly',
|
||||
'Set-Cookie: name=value; expires='.date('D, d-M-Y H:i:s', $tsp).' GMT; Max-Age=5',
|
||||
'Set-Cookie: name=value; expires='.date('D, d-M-Y H:i:s', $tsn).' GMT; Max-Age=0; path=/path/; domain=domain.tld; secure; HttpOnly; SameSite=Strict'
|
||||
);
|
||||
|
||||
$headers = headers_list();
|
||||
|
||||
26
ext/standard/tests/network/setcookie_error.phpt
Normal file
26
ext/standard/tests/network/setcookie_error.phpt
Normal file
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
setcookie() array variant error tests
|
||||
--INI--
|
||||
date.timezone=UTC
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ob_start();
|
||||
|
||||
// Unrecognized key and no valid keys
|
||||
setcookie('name', 'value', ['unknown_key' => 'only']);
|
||||
// Numeric key and no valid keys
|
||||
setcookie('name', 'value', [0 => 'numeric_key']);
|
||||
// Unrecognized key
|
||||
setcookie('name', 'value', ['path' => '/path/', 'foo' => 'bar']);
|
||||
|
||||
--EXPECTF--
|
||||
Warning: setcookie(): Unrecognized key 'unknown_key' found in the options array in %s
|
||||
|
||||
Warning: setcookie(): No valid options were found in the given array in %s
|
||||
|
||||
Warning: setcookie(): Numeric key found in the options array in %s
|
||||
|
||||
Warning: setcookie(): No valid options were found in the given array in %s
|
||||
|
||||
Warning: setcookie(): Unrecognized key 'foo' found in the options array in %s
|
||||
Reference in New Issue
Block a user