From 0b576f6f1135479bbc466dbb29da5a352d853161 Mon Sep 17 00:00:00 2001 From: Matteo Beccati Date: Thu, 23 Apr 2009 13:26:10 +0000 Subject: [PATCH] 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 --- NEWS | 1 + ext/pdo/pdo_stmt.c | 3 +- ext/pdo_oci/tests/bug46274.phpt | 71 ++++++++++++++++++++++++++ ext/pdo_oci/tests/bug46274_2.phpt | 77 +++++++++++++++++++++++++++++ ext/pdo_pgsql/pgsql_statement.c | 10 +++- ext/pdo_pgsql/tests/bug46274_2.phpt | 16 +++--- 6 files changed, 168 insertions(+), 10 deletions(-) create mode 100644 ext/pdo_oci/tests/bug46274.phpt create mode 100644 ext/pdo_oci/tests/bug46274_2.phpt diff --git a/NEWS b/NEWS index 7e4bfa38b8..30c6e91608 100644 --- a/NEWS +++ b/NEWS @@ -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-- + +--FILE-- +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-- + +--FILE-- +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 -- 2.50.1