diff options
author | Yasuo Ohgaki <yohgaki@php.net> | 2015-02-03 15:40:59 +0900 |
---|---|---|
committer | Yasuo Ohgaki <yohgaki@php.net> | 2015-02-03 15:40:59 +0900 |
commit | 30b4a32e09a0bc142ecd7002f0a6eba710a4e997 (patch) | |
tree | 3acabf6ca02abe2cc90c44389c9e77d0a5df8d87 | |
parent | 1aa6242dcf856f799cd2c48a993fa507fbd949e6 (diff) | |
parent | 36f73412c12c1271bf686ba7309aee4169c2dc71 (diff) | |
download | php-git-30b4a32e09a0bc142ecd7002f0a6eba710a4e997.tar.gz |
Merge branch 'PHP-5.6'
* PHP-5.6:
Fixed Bug #65199 pg_copy_from() modifies input array variable
Conflicts:
ext/pgsql/pgsql.c
-rw-r--r-- | ext/pgsql/pgsql.c | 36 | ||||
-rw-r--r-- | ext/pgsql/tests/bug65119.phpt | 40 |
2 files changed, 63 insertions, 13 deletions
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 225ff65c30..d414025ab7 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -4151,7 +4151,7 @@ PHP_FUNCTION(pg_copy_to) PHP_FUNCTION(pg_copy_from) { zval *pgsql_link = NULL, *pg_rows; - zval *tmp; + zval *value; char *table_name, *pg_delim = NULL, *pg_null_as = NULL; size_t table_name_len, pg_delim_len, pg_null_as_len; int pg_null_as_free = 0; @@ -4200,39 +4200,49 @@ PHP_FUNCTION(pg_copy_from) int command_failed = 0; PQclear(pgsql_result); #if HAVE_PQPUTCOPYDATA - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pg_rows), tmp) { - convert_to_string_ex(tmp); - query = (char *)emalloc(Z_STRLEN_P(tmp) + 2); - strlcpy(query, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp) + 2); - if(Z_STRLEN_P(tmp) > 0 && *(query + Z_STRLEN_P(tmp) - 1) != '\n') { - strlcat(query, "\n", Z_STRLEN_P(tmp) + 2); + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pg_rows), value) { + zval tmp; + ZVAL_DUP(&tmp, value); + convert_to_string_ex(&tmp); + query = (char *)emalloc(Z_STRLEN(tmp) + 2); + strlcpy(query, Z_STRVAL(tmp), Z_STRLEN(tmp) + 2); + if(Z_STRLEN(tmp) > 0 && *(query + Z_STRLEN(tmp) - 1) != '\n') { + strlcat(query, "\n", Z_STRLEN(tmp) + 2); } if (PQputCopyData(pgsql, query, (int)strlen(query)) != 1) { efree(query); + zval_dtor(&tmp); PHP_PQ_ERROR("copy failed: %s", pgsql); RETURN_FALSE; } efree(query); + zval_dtor(&tmp); } ZEND_HASH_FOREACH_END(); + if (PQputCopyEnd(pgsql, NULL) != 1) { PHP_PQ_ERROR("putcopyend failed: %s", pgsql); RETURN_FALSE; } #else - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pg_rows), tmp) { - convert_to_string_ex(tmp); - query = (char *)emalloc(Z_STRLEN_P(tmp) + 2); - strlcpy(query, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp) + 2); - if(Z_STRLEN_P(tmp) > 0 && *(query + Z_STRLEN_P(tmp) - 1) != '\n') { - strlcat(query, "\n", Z_STRLEN_P(tmp) + 2); + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pg_rows), value) { + zval tmp; + ZVAL_DUP(&tmp, value); + convert_to_string_ex(&tmp); + query = (char *)emalloc(Z_STRLEN(tmp) + 2); + strlcpy(query, Z_STRVAL(tmp), Z_STRLEN(tmp) + 2); + if(Z_STRLEN(tmp) > 0 && *(query + Z_STRLEN(tmp) - 1) != '\n') { + strlcat(query, "\n", Z_STRLEN(tmp) + 2); } if (PQputline(pgsql, query)==EOF) { efree(query); + zval_dtor(&tmp); PHP_PQ_ERROR("copy failed: %s", pgsql); RETURN_FALSE; } efree(query); + zval_dtor(&tmp); } ZEND_HASH_FOREACH_END(); + if (PQputline(pgsql, "\\.\n") == EOF) { PHP_PQ_ERROR("putline failed: %s", pgsql); RETURN_FALSE; diff --git a/ext/pgsql/tests/bug65119.phpt b/ext/pgsql/tests/bug65119.phpt new file mode 100644 index 0000000000..c02ff28f06 --- /dev/null +++ b/ext/pgsql/tests/bug65119.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug #65119 (pg_copy_from() modifies input array variable) +--SKIPIF-- +<?php +include("skipif.inc"); +?> +--FILE-- +<?php +include 'config.inc'; + +function test(Array $values, $conn_str) { + $connection = pg_pconnect($conn_str, PGSQL_CONNECT_FORCE_NEW); + pg_query("begin"); + pg_query("CREATE TABLE bug65119 (i INTEGER)"); + pg_copy_from($connection, "bug65119", $values, "\t", "NULL"); + pg_query("rollback"); +} + +$values = Array(1,2,3); +var_dump($values); +test($values, $conn_str); +var_dump($values); +?> +--EXPECT-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} |