diff options
author | Matteo Beccati <mbeccati@php.net> | 2009-04-23 13:26:10 +0000 |
---|---|---|
committer | Matteo Beccati <mbeccati@php.net> | 2009-04-23 13:26:10 +0000 |
commit | 0b576f6f1135479bbc466dbb29da5a352d853161 (patch) | |
tree | b0288acc381f5ed85d9848df4a3656e39ba7f6c1 | |
parent | b7747cf30c7d79ba20030d4dc9b8d897c9d1400c (diff) | |
download | php-git-0b576f6f1135479bbc466dbb29da5a352d853161.tar.gz |
MFH:
- Reverted previous fix for bug #46274 and properly fixed it
- Fixed bug #48060
# Also added tests for pdo_oci as it's the only other driver currently
# using streams: no regression found
-rw-r--r-- | NEWS | 1 | ||||
-rwxr-xr-x | ext/pdo/pdo_stmt.c | 3 | ||||
-rw-r--r-- | ext/pdo_oci/tests/bug46274.phpt | 71 | ||||
-rw-r--r-- | ext/pdo_oci/tests/bug46274_2.phpt | 77 | ||||
-rw-r--r-- | ext/pdo_pgsql/pgsql_statement.c | 10 | ||||
-rw-r--r-- | ext/pdo_pgsql/tests/bug46274_2.phpt | 16 |
6 files changed, 168 insertions, 10 deletions
@@ -12,6 +12,7 @@ PHP NEWS disable this behaviour using "http"=>array("auto_decode"=>0) in stream context. (Dmitry) +- Fixed bug #48060 (pdo_pgsql - large objects are returned as empty). (Matteo) - Fixed bug #48023 (spl_autoload_register didn't store closures). (Etienne) - Fixed bug #48004 (Error handler prevents creation of default object). (Dmitry) diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 838a235169..0800d23d29 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -589,9 +589,8 @@ static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno, int *typ case PDO_PARAM_LOB: if (value == NULL) { ZVAL_NULL(dest); - } else if (value[0] == '\0') { - ZVAL_EMPTY_STRING(dest); } else if (value_len == 0) { + /* Warning, empty strings need to be passed as stream */ if (stmt->dbh->stringify || new_type == PDO_PARAM_STR) { char *buf = NULL; size_t len; diff --git a/ext/pdo_oci/tests/bug46274.phpt b/ext/pdo_oci/tests/bug46274.phpt new file mode 100644 index 0000000000..23ee8ee20f --- /dev/null +++ b/ext/pdo_oci/tests/bug46274.phpt @@ -0,0 +1,71 @@ +--TEST-- +Bug #46274 (pdo_pgsql - Segfault when using PDO::ATTR_STRINGIFY_FETCHES and blob) +--SKIPIF-- +<?php +if (!extension_loaded('pdo') || !extension_loaded('pdo_oci')) +die('skip not loaded'); +require dirname(__FILE__).'/../../pdo/tests/pdo_test.inc'; +PDOTest::skip(); +?> +--FILE-- +<?php +require 'ext/pdo/tests/pdo_test.inc'; +$db = PDOTest::test_factory('ext/pdo_oci/tests/common.phpt'); +$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); + +try { + $db->exec("DROP TABLE test_one_blob"); +} catch (Exception $e) { +} + +$db->beginTransaction(); + +$db->query('CREATE TABLE test_one_blob (id INT NOT NULL, blob1 BLOB)'); + +$stmt = $db->prepare("INSERT INTO test_one_blob (id, blob1) VALUES (:id, EMPTY_BLOB()) RETURNING blob1 INTO :foo"); + +$data = 'foo'; +$blob = fopen('php://memory', 'a'); +fwrite($blob, $data); +rewind($blob); + +$id = 1; +$stmt->bindparam(':id', $id); +$stmt->bindparam(':foo', $blob, PDO::PARAM_LOB); +$stmt->execute(); + +$data = ''; +$blob = fopen('php://memory', 'a'); +fwrite($blob, $data); +rewind($blob); + +$id = 1; +$stmt->bindparam(':id', $id); +$stmt->bindparam(':foo', $blob, PDO::PARAM_LOB); +$stmt->execute(); + +$res = $db->query("SELECT blob1 from test_one_blob"); +// Resource +var_dump($res->fetch()); + +// Empty string +var_dump($res->fetch()); + +$db->exec("DROP TABLE test_one_blob"); + +?> +--EXPECTF-- +array(2) { + ["blob1"]=> + string(3) "foo" + [0]=> + string(3) "foo" +} +array(2) { + ["blob1"]=> + string(0) "" + [0]=> + string(0) "" +} diff --git a/ext/pdo_oci/tests/bug46274_2.phpt b/ext/pdo_oci/tests/bug46274_2.phpt new file mode 100644 index 0000000000..cbadcef4f8 --- /dev/null +++ b/ext/pdo_oci/tests/bug46274_2.phpt @@ -0,0 +1,77 @@ +--TEST-- +Bug #46274 (pdo_pgsql - Segfault when using PDO::ATTR_STRINGIFY_FETCHES and blob) +--SKIPIF-- +<?php +if (!extension_loaded('pdo') || !extension_loaded('pdo_oci')) +die('skip not loaded'); +require dirname(__FILE__).'/../../pdo/tests/pdo_test.inc'; +PDOTest::skip(); +?> +--FILE-- +<?php +require 'ext/pdo/tests/pdo_test.inc'; +$db = PDOTest::test_factory('ext/pdo_oci/tests/common.phpt'); +$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false); + +try { + $db->exec("DROP TABLE test_one_blob"); +} catch (Exception $e) { +} + +$db->beginTransaction(); + +$db->query('CREATE TABLE test_one_blob (id INT NOT NULL, blob1 BLOB)'); + +$stmt = $db->prepare("INSERT INTO test_one_blob (id, blob1) VALUES (:id, EMPTY_BLOB()) RETURNING blob1 INTO :foo"); + +$data = 'foo'; +$blob = fopen('php://memory', 'a'); +fwrite($blob, $data); +rewind($blob); + +$id = 1; +$stmt->bindparam(':id', $id); +$stmt->bindparam(':foo', $blob, PDO::PARAM_LOB); +$stmt->execute(); + +$data = ''; +$blob = fopen('php://memory', 'a'); +fwrite($blob, $data); +rewind($blob); + +$id = 1; +$stmt->bindparam(':id', $id); +$stmt->bindparam(':foo', $blob, PDO::PARAM_LOB); +$stmt->execute(); + +$res = $db->query("SELECT blob1 from test_one_blob"); +// Resource +var_dump($row = $res->fetch()); +var_dump(fread($row[0], 1024)); +fclose($row[0]); + +// Empty string +var_dump($row = $res->fetch()); +var_dump(fread($row[0], 1024)); +fclose($row[0]); + +$db->exec("DROP TABLE test_one_blob"); + +?> +--EXPECTF-- +array(2) { + ["blob1"]=> + resource(%d) of type (stream) + [0]=> + resource(%d) of type (stream) +} +string(3) "foo" +array(2) { + ["blob1"]=> + resource(%d) of type (stream) + [0]=> + resource(%d) of type (stream) +} +string(0) "" diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index d711ecff29..8a7882ffe4 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -619,8 +619,14 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned return 0; } else { *ptr = php_pdo_pgsql_unescape_bytea(*ptr, &tmp_len); - *len = tmp_len; - *caller_frees = 1; + if (!tmp_len) { + /* Empty string, return as empty stream */ + *ptr = (char *)php_stream_memory_open(TEMP_STREAM_READONLY, "", 0); + *len = 0; + } else { + *len = tmp_len; + *caller_frees = 1; + } } break; case PDO_PARAM_NULL: diff --git a/ext/pdo_pgsql/tests/bug46274_2.phpt b/ext/pdo_pgsql/tests/bug46274_2.phpt index 5e35556880..eb675afe9e 100644 --- a/ext/pdo_pgsql/tests/bug46274_2.phpt +++ b/ext/pdo_pgsql/tests/bug46274_2.phpt @@ -47,11 +47,13 @@ $res = $db->query("SELECT blob1 from test_one_blob"); var_dump($x = $res->fetch()); var_dump(fread($x['blob1'], 10)); -// Empty string +// Resource var_dump($res->fetch()); +var_dump(fread($x['blob1'], 10)); -// Empty string +// Resource var_dump($res->fetch()); +var_dump(fread($x['blob1'], 10)); // NULL var_dump($res->fetch()); @@ -69,16 +71,18 @@ array(2) { string(3) "foo" array(2) { ["blob1"]=> - string(0) "" + resource(%d) of type (stream) [0]=> - string(0) "" + resource(%d) of type (stream) } +string(0) "" array(2) { ["blob1"]=> - string(0) "" + resource(%d) of type (stream) [0]=> - string(0) "" + resource(%d) of type (stream) } +string(0) "" array(2) { ["blob1"]=> NULL |