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)