From 2bcb3f119288b551d49b19358bdfa48b5ee4985e Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 26 Mar 2025 12:47:57 +0000 Subject: [PATCH] Fix GH-18148: pg_copy_from() wrong \n offset check. --- ext/pgsql/pgsql.c | 6 ++++-- ext/pgsql/tests/gh18148.phpt | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 ext/pgsql/tests/gh18148.phpt diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 4b03bfc3c9df4..c0d4a5117aefc 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -3451,11 +3451,13 @@ PHP_FUNCTION(pg_copy_from) if (UNEXPECTED(!tmp)) { return; } - zend_string *zquery = zend_string_alloc(ZSTR_LEN(tmp) + 1, false); + // we give allocation room for a potential command line `\n` terminator addition + zend_string *zquery = zend_string_alloc(ZSTR_LEN(tmp) + 2, false); memcpy(ZSTR_VAL(zquery), ZSTR_VAL(tmp), ZSTR_LEN(tmp) + 1); ZSTR_LEN(zquery) = ZSTR_LEN(tmp); - if (ZSTR_LEN(tmp) > 0 && ZSTR_VAL(zquery)[ZSTR_LEN(tmp)] != '\n') { + if (ZSTR_LEN(tmp) > 0 && ZSTR_VAL(zquery)[ZSTR_LEN(tmp) - 1] != '\n') { ZSTR_VAL(zquery)[ZSTR_LEN(tmp)] = '\n'; + ZSTR_VAL(zquery)[ZSTR_LEN(tmp) + 1] = '\0'; ZSTR_LEN(zquery) ++; } if (PQputCopyData(pgsql, ZSTR_VAL(zquery), ZSTR_LEN(zquery)) != 1) { diff --git a/ext/pgsql/tests/gh18148.phpt b/ext/pgsql/tests/gh18148.phpt new file mode 100644 index 0000000000000..6cc2a2542086f --- /dev/null +++ b/ext/pgsql/tests/gh18148.phpt @@ -0,0 +1,24 @@ +--TEST-- +Fix GH-18148 pg_copy_from() command position offset when giving explicit \n terminator +--EXTENSIONS-- +pgsql +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true)