Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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).
  • Loading branch information...
commit 30e0442c549bd20288ca8754daa0cdf24d98f055 1 parent cc66eaa
@LawnGnome LawnGnome authored
Showing with 61 additions and 6 deletions.
  1. +4 −0 NEWS
  2. +19 −6 ext/dba/dba.c
  3. +38 −0 ext/dba/tests/bug65708.phpt
View
4 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).
View
25 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)
{
View
38 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
Please sign in to comment.
Something went wrong with that request. Please try again.