Bug #23955: allow specifiy max age for setcookie()

This commit is contained in:
Lars Strojny 2013-01-06 03:22:44 +01:00
parent f3824ad166
commit ec2fff80e7
4 changed files with 87 additions and 7 deletions

1
NEWS
View file

@ -7,6 +7,7 @@ PHP NEWS
. Fixed bug #63822 (Crash when using closures with ArrayAccess). . Fixed bug #63822 (Crash when using closures with ArrayAccess).
(Nikita Popov) (Nikita Popov)
. Add Generator::throw() method. (Nikita Popov) . Add Generator::throw() method. (Nikita Popov)
. Bug #23955: allow specifying Max-Age attribute in setcookie() (narfbg, Lars)
- cURL: - cURL:
. Added new functions curl_escape, curl_multi_setopt, curl_multi_strerror . Added new functions curl_escape, curl_multi_setopt, curl_multi_strerror

View file

@ -1154,6 +1154,7 @@ static int php_session_cache_limiter(TSRMLS_D) /* {{{ */
#define COOKIE_SET_COOKIE "Set-Cookie: " #define COOKIE_SET_COOKIE "Set-Cookie: "
#define COOKIE_EXPIRES "; expires=" #define COOKIE_EXPIRES "; expires="
#define COOKIE_MAX_AGE "; Max-Age="
#define COOKIE_PATH "; path=" #define COOKIE_PATH "; path="
#define COOKIE_DOMAIN "; domain=" #define COOKIE_DOMAIN "; domain="
#define COOKIE_SECURE "; secure" #define COOKIE_SECURE "; secure"
@ -1201,6 +1202,9 @@ static void php_session_send_cookie(TSRMLS_D) /* {{{ */
smart_str_appends(&ncookie, COOKIE_EXPIRES); smart_str_appends(&ncookie, COOKIE_EXPIRES);
smart_str_appends(&ncookie, date_fmt); smart_str_appends(&ncookie, date_fmt);
efree(date_fmt); efree(date_fmt);
smart_str_appends(&ncookie, COOKIE_MAX_AGE);
smart_str_append_long(&ncookie, PS(cookie_lifetime));
} }
} }

View file

@ -40,11 +40,11 @@ PHP_FUNCTION(header)
{ {
zend_bool rep = 1; zend_bool rep = 1;
sapi_header_line ctr = {0}; sapi_header_line ctr = {0};
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
&ctr.line_len, &rep, &ctr.response_code) == FAILURE) &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
return; return;
sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
} }
/* }}} */ /* }}} */
@ -80,7 +80,7 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
char *dt; char *dt;
sapi_header_line ctr = {0}; sapi_header_line ctr = {0};
int result; int result;
if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */
zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" ); zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" );
return FAILURE; return FAILURE;
@ -111,18 +111,19 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
cookie = emalloc(len + 100); cookie = emalloc(len + 100);
if (value && value_len == 0) { if (value && value_len == 0) {
/* /*
* MSIE doesn't delete a cookie when you set it to a null value * MSIE doesn't delete a cookie when you set it to a null value
* so in order to force cookies to be deleted, even on MSIE, we * so in order to force cookies to be deleted, even on MSIE, we
* pick an expiry date in the past * pick an expiry date in the past
*/ */
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, 1, 0 TSRMLS_CC); dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, 1, 0 TSRMLS_CC);
snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s", name, dt); snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s; Max-Age=0", name, dt);
efree(dt); efree(dt);
} else { } else {
snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value : ""); snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value : "");
if (expires > 0) { if (expires > 0) {
const char *p; const char *p;
char tsdelta[13];
strlcat(cookie, "; expires=", len + 100); strlcat(cookie, "; expires=", len + 100);
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC); dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC);
/* check to make sure that the year does not exceed 4 digits in length */ /* check to make sure that the year does not exceed 4 digits in length */
@ -136,6 +137,10 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
} }
strlcat(cookie, dt, len + 100); strlcat(cookie, dt, len + 100);
efree(dt); efree(dt);
snprintf(tsdelta, sizeof(tsdelta), "%li", (long) difftime(expires, time(NULL)));
strlcat(cookie, "; Max-Age=", len + 100);
strlcat(cookie, tsdelta, len + 100);
} }
} }
@ -237,11 +242,11 @@ PHP_FUNCTION(headers_sent)
ZVAL_LONG(arg2, line); ZVAL_LONG(arg2, line);
case 1: case 1:
zval_dtor(arg1); zval_dtor(arg1);
if (file) { if (file) {
ZVAL_STRING(arg1, file, 1); ZVAL_STRING(arg1, file, 1);
} else { } else {
ZVAL_STRING(arg1, "", 1); ZVAL_STRING(arg1, "", 1);
} }
break; break;
} }

View file

@ -0,0 +1,70 @@
--TEST--
setcookie() tests
--DESCRIPTION--
--INI--
date.timezone=UTC
--FILE--
<?php
setcookie('name');
setcookie('name', 'value');
setcookie('name', 'space value');
setcookie('name', 'value', 0);
setcookie('name', 'value', $tsp = time() + 5);
setcookie('name', 'value', $tsn = time() - 6);
setcookie('name', 'value', $tsc = time());
setcookie('name', 'value', 0, '/path/');
setcookie('name', 'value', 0, '', 'domain.tld');
setcookie('name', 'value', 0, '', '', TRUE);
setcookie('name', 'value', 0, '', '', FALSE, TRUE);
$expected = array(
'Set-Cookie: name=',
'Set-Cookie: name=value',
'Set-Cookie: name=space+value',
'Set-Cookie: name=value',
'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=-6',
'Set-Cookie: name=value; expires='.date('D, d-M-Y H:i:s', $tsc).' GMT; Max-Age=0',
'Set-Cookie: name=value; path=/path/',
'Set-Cookie: name=value; domain=domain.tld',
'Set-Cookie: name=value; secure',
'Set-Cookie: name=value; httponly'
);
$headers = headers_list();
if (($i = count($expected)) > count($headers))
{
echo "Less headers are being sent than expected - aborting";
return;
}
do
{
if (strncmp(current($headers), 'Set-Cookie:', 11) !== 0)
{
continue;
}
if (current($headers) === current($expected))
{
$i--;
}
else
{
echo "Header mismatch:\n\tExpected: "
.current($expected)
."\n\tReceived: ".current($headers)."\n";
}
next($expected);
}
while (next($headers) !== FALSE);
echo ($i === 0)
? 'OK'
: 'A total of '.$i.' errors found.';
--EXPECTHEADERS--
--EXPECT--
OK