diff options
author | Rasmus Lerdorf <rasmus@php.net> | 2013-11-07 18:09:15 -0800 |
---|---|---|
committer | Rasmus Lerdorf <rasmus@php.net> | 2013-11-07 18:09:15 -0800 |
commit | b3d522d215681d641e9827e10f1b09a7659bc589 (patch) | |
tree | 5f402ff33ee10e0beaed0f01d751a11ae0ac8288 /ext/pdo | |
parent | 54fe719953eec91e4416addae1bda2c3f9ce82bb (diff) | |
parent | 890ea8411f908ee8ab84389b42066f66d4a033e6 (diff) | |
download | php-git-b3d522d215681d641e9827e10f1b09a7659bc589.tar.gz |
Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4:
Fix bug #65946 - pdo_sql_parser.c permanently converts values bound to strings
Conflicts:
ext/pdo/pdo_sql_parser.c
Diffstat (limited to 'ext/pdo')
-rw-r--r-- | ext/pdo/pdo_sql_parser.c | 23 | ||||
-rw-r--r-- | ext/pdo/pdo_sql_parser.re | 23 | ||||
-rw-r--r-- | ext/pdo/tests/bug65946.phpt | 33 |
3 files changed, 59 insertions, 20 deletions
diff --git a/ext/pdo/pdo_sql_parser.c b/ext/pdo/pdo_sql_parser.c index aea362fdb2..37d8752d62 100644 --- a/ext/pdo/pdo_sql_parser.c +++ b/ext/pdo/pdo_sql_parser.c @@ -586,7 +586,9 @@ safe: } plc->freeq = 1; } else { - switch (Z_TYPE_P(param->parameter)) { + zval tmp_param = *param->parameter; + zval_copy_ctor(&tmp_param); + switch (Z_TYPE(tmp_param)) { case IS_NULL: plc->quoted = "NULL"; plc->qlen = sizeof("NULL")-1; @@ -594,20 +596,20 @@ safe: break; case IS_BOOL: - convert_to_long(param->parameter); - + convert_to_long(&tmp_param); + /* fall through */ case IS_LONG: case IS_DOUBLE: - convert_to_string(param->parameter); - plc->qlen = Z_STRLEN_P(param->parameter); - plc->quoted = Z_STRVAL_P(param->parameter); - plc->freeq = 0; + convert_to_string(&tmp_param); + plc->qlen = Z_STRLEN(tmp_param); + plc->quoted = estrdup(Z_STRVAL(tmp_param)); + plc->freeq = 1; break; default: - convert_to_string(param->parameter); - if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), - Z_STRLEN_P(param->parameter), &plc->quoted, &plc->qlen, + convert_to_string(&tmp_param); + if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL(tmp_param), + Z_STRLEN(tmp_param), &plc->quoted, &plc->qlen, param->param_type TSRMLS_CC)) { /* bork */ ret = -1; @@ -616,6 +618,7 @@ safe: } plc->freeq = 1; } + zval_dtor(&tmp_param); } } else { plc->quoted = Z_STRVAL_P(param->parameter); diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index 1936a37340..fa8ef187fa 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -228,7 +228,9 @@ safe: } plc->freeq = 1; } else { - switch (Z_TYPE_P(param->parameter)) { + zval tmp_param = *param->parameter; + zval_copy_ctor(&tmp_param); + switch (Z_TYPE(tmp_param)) { case IS_NULL: plc->quoted = "NULL"; plc->qlen = sizeof("NULL")-1; @@ -236,20 +238,20 @@ safe: break; case IS_BOOL: - convert_to_long(param->parameter); - + convert_to_long(&tmp_param); + /* fall through */ case IS_LONG: case IS_DOUBLE: - convert_to_string(param->parameter); - plc->qlen = Z_STRLEN_P(param->parameter); - plc->quoted = Z_STRVAL_P(param->parameter); - plc->freeq = 0; + convert_to_string(&tmp_param); + plc->qlen = Z_STRLEN(tmp_param); + plc->quoted = estrdup(Z_STRVAL(tmp_param)); + plc->freeq = 1; break; default: - convert_to_string(param->parameter); - if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), - Z_STRLEN_P(param->parameter), &plc->quoted, &plc->qlen, + convert_to_string(&tmp_param); + if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL(tmp_param), + Z_STRLEN(tmp_param), &plc->quoted, &plc->qlen, param->param_type TSRMLS_CC)) { /* bork */ ret = -1; @@ -258,6 +260,7 @@ safe: } plc->freeq = 1; } + zval_dtor(&tmp_param); } } else { plc->quoted = Z_STRVAL_P(param->parameter); diff --git a/ext/pdo/tests/bug65946.phpt b/ext/pdo/tests/bug65946.phpt new file mode 100644 index 0000000000..30261d638a --- /dev/null +++ b/ext/pdo/tests/bug65946.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #65946 (pdo_sql_parser.c permanently converts values bound to strings) +--SKIPIF-- +<?php +if (!extension_loaded('pdo')) die('skip'); +$dir = getenv('REDIR_TEST_DIR'); +if (false == $dir) die('skip no driver'); +require_once $dir . 'pdo_test.inc'; +PDOTest::skip(); +?> +--FILE-- +<?php +if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/'); +require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; +$db = PDOTest::factory(); +$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); +$db->exec('CREATE TABLE test(id int)'); +$db->exec('INSERT INTO test VALUES(1)'); +$db->exec('INSERT INTO test VALUES(2)'); +$stmt = $db->prepare('SELECT * FROM testtable LIMIT :limit'); +$stmt->bindValue('limit', 1, PDO::PARAM_INT); +if(!($res = $stmt->execute())) var_dump($stmt->errorInfo()); +if(!($res = $stmt->execute())) var_dump($stmt->errorInfo()); +var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); +?> +--EXPECTF-- +array(1) { + [0]=> + array(1) { + ["id"]=> + string(1) "2" + } +} |