diff --git a/ext/standard/file.c b/ext/standard/file.c index 5e835239a8ccd..edaba57748cb3 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -2017,7 +2017,14 @@ PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure memcpy(tptr, line_end, line_end_len); tptr += line_end_len; + /* nothing can be fetched if stream is NULL (e.g. str_getcsv()) */ if (stream == NULL) { + /* the enclosure is unterminated */ + if (bptr > limit) { + /* if the line ends with enclosure, we need to go back by + * one character so the \0 character is not copied. */ + --bptr; + } goto quit_loop_2; } @@ -2028,6 +2035,11 @@ PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure * assign all the data from the start of * the enclosure to end of data to the * last element */ + if (bptr > limit) { + /* if the line ends with enclosure, we need to go back by + * one character so the \0 character is not copied. */ + --bptr; + } goto quit_loop_2; } diff --git a/ext/standard/tests/file/fgetcsv_variation33.phpt b/ext/standard/tests/file/fgetcsv_variation33.phpt new file mode 100644 index 0000000000000..7dfb1437e9ea9 --- /dev/null +++ b/ext/standard/tests/file/fgetcsv_variation33.phpt @@ -0,0 +1,29 @@ +--TEST-- +fgetcsv() with unterminated enclosure at the end of file +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + string(5) "cell1" + [1]=> + string(5) "cell2" +} +array(2) { + [0]=> + string(5) "cell1" + [1]=> + string(0) "" +} diff --git a/ext/standard/tests/strings/gh11982.phpt b/ext/standard/tests/strings/gh11982.phpt new file mode 100644 index 0000000000000..9b500a63c93cb --- /dev/null +++ b/ext/standard/tests/strings/gh11982.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-11982 (str_getcsv returns null byte for unterminated quoted string) +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + string(0) "" +} +array(2) { + [0]=> + string(5) "field" + [1]=> + string(0) "" +} +array(2) { + [0]=> + string(0) "" + [1]=> + string(1) "a" +} +