From f8a8ccaba2b6c025b686fab60c6e4a1601d81e62 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Tue, 3 Feb 2015 15:26:02 +0900 Subject: Fixed Bug #65199 pg_copy_from() modifies input array variable --- ext/pgsql/pgsql.c | 36 ++++++++++++++++++++++++++---------- ext/pgsql/tests/bug65119.phpt | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 ext/pgsql/tests/bug65119.phpt diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 426de41ae9..33e65767cf 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -4059,18 +4059,26 @@ PHP_FUNCTION(pg_copy_from) zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(pg_rows), &pos); #if HAVE_PQPUTCOPYDATA while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) { - convert_to_string_ex(tmp); - query = (char *)emalloc(Z_STRLEN_PP(tmp) + 2); - strlcpy(query, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp) + 2); - if(Z_STRLEN_PP(tmp) > 0 && *(query + Z_STRLEN_PP(tmp) - 1) != '\n') { - strlcat(query, "\n", Z_STRLEN_PP(tmp) + 2); + zval *value; + ALLOC_ZVAL(value); + INIT_PZVAL_COPY(value, *tmp); + zval_copy_ctor(value); + convert_to_string_ex(&value); + query = (char *)emalloc(Z_STRLEN_P(value) + 2); + strlcpy(query, Z_STRVAL_P(value), Z_STRLEN_P(value) + 2); + if(Z_STRLEN_P(value) > 0 && *(query + Z_STRLEN_P(value) - 1) != '\n') { + strlcat(query, "\n", Z_STRLEN_P(value) + 2); } if (PQputCopyData(pgsql, query, strlen(query)) != 1) { efree(query); + zval_dtor(value); + efree(value); PHP_PQ_ERROR("copy failed: %s", pgsql); RETURN_FALSE; } efree(query); + zval_dtor(value); + efree(value); zend_hash_move_forward_ex(Z_ARRVAL_P(pg_rows), &pos); } if (PQputCopyEnd(pgsql, NULL) != 1) { @@ -4079,18 +4087,26 @@ PHP_FUNCTION(pg_copy_from) } #else while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) { - convert_to_string_ex(tmp); - query = (char *)emalloc(Z_STRLEN_PP(tmp) + 2); - strlcpy(query, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp) + 2); - if(Z_STRLEN_PP(tmp) > 0 && *(query + Z_STRLEN_PP(tmp) - 1) != '\n') { - strlcat(query, "\n", Z_STRLEN_PP(tmp) + 2); + zval *value; + ALLOC_ZVAL(value); + INIT_PZVAL_COPY(value, *tmp); + zval_copy_ctor(value); + convert_to_string_ex(&value); + query = (char *)emalloc(Z_STRLEN_P(value) + 2); + strlcpy(query, Z_STRVAL_P(value), Z_STRLEN_P(value) + 2); + if(Z_STRLEN_P(value) > 0 && *(query + Z_STRLEN_P(value) - 1) != '\n') { + strlcat(query, "\n", Z_STRLEN_P(value) + 2); } if (PQputline(pgsql, query)==EOF) { efree(query); + zval_dtor(value); + efree(value); PHP_PQ_ERROR("copy failed: %s", pgsql); RETURN_FALSE; } efree(query); + zval_dtor(value); + efree(value); zend_hash_move_forward_ex(Z_ARRVAL_P(pg_rows), &pos); } if (PQputline(pgsql, "\\.\n") == EOF) { 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-- + +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} -- cgit v1.2.1