diff options
| author | Adam Harvey <aharvey@php.net> | 2013-09-22 16:46:17 -0700 |
|---|---|---|
| committer | Adam Harvey <aharvey@php.net> | 2013-09-22 16:46:17 -0700 |
| commit | 30e0442c549bd20288ca8754daa0cdf24d98f055 (patch) | |
| tree | 2ffe61739fa2e38048edbced922ab9b414e450e4 /ext/dba/dba.c | |
| parent | cc66eaa04b123bdfb6aaa7305713fa508640999e (diff) | |
| download | php-git-30e0442c549bd20288ca8754daa0cdf24d98f055.tar.gz | |
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).
Diffstat (limited to 'ext/dba/dba.c')
| -rw-r--r-- | ext/dba/dba.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/ext/dba/dba.c b/ext/dba/dba.c index 8005101de3..50a94dd2ad 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) { |
