Commit: 30e0442c549bd20288ca8754daa0cdf24d98f055 Author: Adam Harvey <ahar...@php.net> Sun, 22 Sep 2013 16:46:17 -0700 Parents: cc66eaa04b123bdfb6aaa7305713fa508640999e Branches: PHP-5.4 PHP-5.5 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=30e0442c549bd20288ca8754daa0cdf24d98f055 Log: Copy dba_*() keys before converting to string. A nice Sunday afternoon project for somebody would be to refactor the dba functions to use zend_parse_parameters() reliably and try to untangle some of the macros in dba.c. Sadly, it is not a nice Sunday afternoon here. Fixes bug #65708 (dba functions cast $key param to string in-place, bypassing copy on write). Bugs: https://bugs.php.net/65708 Changed paths: M NEWS M ext/dba/dba.c A ext/dba/tests/bug65708.phpt Diff: diff --git a/NEWS b/NEWS index bb170e7..e176325 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,10 @@ PHP NEWS . Fixed bug #64157 (DateTime::createFromFormat() reports confusing error message). (Boro Sitnikovski) +- DBA extension: + . Fixed bug #65708 (dba functions cast $key param to string in-place, + bypassing copy on write). (Adam) + - Filter: . Add RFC 6598 IPs to reserved addresses. (Sebastian Nohn) . Fixed bug #64441 (FILTER_VALIDATE_URL rejects fully qualified domain names). diff --git a/ext/dba/dba.c b/ext/dba/dba.c index 8005101..50a94dd 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -226,12 +226,17 @@ static size_t php_dba_make_key(zval *key, char **key_str, char **key_free TSRMLS *key_free = *key_str; return len; } else { - *key_free = NULL; + zval tmp = *key; + int len; - convert_to_string(key); - *key_str = Z_STRVAL_P(key); + zval_copy_ctor(&tmp); + convert_to_string(&tmp); - return Z_STRLEN_P(key); + *key_free = *key_str = estrndup(Z_STRVAL(tmp), Z_STRLEN(tmp)); + len = Z_STRLEN(tmp); + + zval_dtor(&tmp); + return len; } } /* }}} */ @@ -297,6 +302,14 @@ static size_t php_dba_make_key(zval *key, char **key_str, char **key_free TSRMLS RETURN_FALSE; \ } +/* the same check, but with a call to DBA_ID_DONE before returning */ +#define DBA_WRITE_CHECK_WITH_ID \ + if(info->mode != DBA_WRITER && info->mode != DBA_TRUNC && info->mode != DBA_CREAT) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "You cannot perform a modification to a database without proper access"); \ + DBA_ID_DONE; \ + RETURN_FALSE; \ + } + /* }}} */ /* {{{ globals */ @@ -557,7 +570,7 @@ static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode) DBA_FETCH_RESOURCE(info, &id); - DBA_WRITE_CHECK; + DBA_WRITE_CHECK_WITH_ID; if (info->hnd->update(info, key_str, key_len, val, val_len, mode TSRMLS_CC) == SUCCESS) { DBA_ID_DONE; @@ -1110,7 +1123,7 @@ PHP_FUNCTION(dba_delete) { DBA_ID_GET2; - DBA_WRITE_CHECK; + DBA_WRITE_CHECK_WITH_ID; if(info->hnd->delete(info, key_str, key_len TSRMLS_CC) == SUCCESS) { diff --git a/ext/dba/tests/bug65708.phpt b/ext/dba/tests/bug65708.phpt new file mode 100644 index 0000000..b77138f --- /dev/null +++ b/ext/dba/tests/bug65708.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #65708 (dba functions cast $key param to string in-place, bypassing copy on write) +--SKIPIF-- +<?php + require_once(dirname(__FILE__) .'/skipif.inc'); +?> +--FILE-- +<?php + +error_reporting(E_ALL); + +require_once(dirname(__FILE__) .'/test.inc'); + +$db = dba_popen($db_filename, 'c'); + +$key = 1; +$copy = $key; + +echo gettype($key)."\n"; +echo gettype($copy)."\n"; + +dba_exists($key, $db); + +echo gettype($key)."\n"; +echo gettype($copy)."\n"; + +dba_close($db); + +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECT-- +integer +integer +integer +integer -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php