Skip to content

Commit 4ccf0b0

Browse files
authoredJul 8, 2022
Make php_fgetcsv() return a HashTale instead of in-out zval param (#8936)
Also refactor what happens on an empty line to return NULL instead of setting the array to [NULL] which makes no design sense at all. However, as this is the current behaviour create a BC Shim inline function to recreate this weird HashTable in the functions which currently use this API
1 parent 247de8a commit 4ccf0b0

File tree

4 files changed

+38
-11
lines changed

4 files changed

+38
-11
lines changed
 

‎ext/spl/spl_directory.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -1958,7 +1958,11 @@ static zend_result spl_filesystem_file_read_csv(spl_filesystem_object *intern, c
19581958
ZVAL_UNDEF(&intern->u.file.current_zval);
19591959
}
19601960

1961-
php_fgetcsv(intern->u.file.stream, delimiter, enclosure, escape, buf_len, buf, &intern->u.file.current_zval);
1961+
HashTable *values = php_fgetcsv(intern->u.file.stream, delimiter, enclosure, escape, buf_len, buf);
1962+
if (values == NULL) {
1963+
values = php_bc_fgetcsv_empty_line();
1964+
}
1965+
ZVAL_ARR(&intern->u.file.current_zval, values);
19621966
if (return_value) {
19631967
ZVAL_COPY(return_value, &intern->u.file.current_zval);
19641968
}

‎ext/standard/file.c

+26-8
Original file line numberDiff line numberDiff line change
@@ -2050,11 +2050,24 @@ PHP_FUNCTION(fgetcsv)
20502050
}
20512051
}
20522052

2053-
php_fgetcsv(stream, delimiter, enclosure, escape, buf_len, buf, return_value);
2053+
HashTable *values = php_fgetcsv(stream, delimiter, enclosure, escape, buf_len, buf);
2054+
if (values == NULL) {
2055+
values = php_bc_fgetcsv_empty_line();
2056+
}
2057+
RETURN_ARR(values);
20542058
}
20552059
/* }}} */
20562060

2057-
PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int escape_char, size_t buf_len, char *buf, zval *return_value) /* {{{ */
2061+
PHPAPI HashTable *php_bc_fgetcsv_empty_line(void)
2062+
{
2063+
HashTable *values = zend_new_array(1);
2064+
zval tmp;
2065+
ZVAL_NULL(&tmp);
2066+
zend_hash_next_index_insert(values, &tmp);
2067+
return values;
2068+
}
2069+
2070+
PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int escape_char, size_t buf_len, char *buf) /* {{{ */
20582071
{
20592072
char *temp, *bptr, *line_end, *limit;
20602073
size_t temp_len, line_end_len;
@@ -2078,12 +2091,11 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int
20782091
temp_len = buf_len;
20792092
temp = emalloc(temp_len + line_end_len + 1);
20802093

2081-
/* Initialize return array */
2082-
array_init(return_value);
2094+
/* Initialize values HashTable */
2095+
HashTable *values = zend_new_array(0);
20832096

20842097
/* Main loop to read CSV fields */
2085-
/* NB this routine will return a single null entry for a blank line */
2086-
2098+
/* NB this routine will return NULL for a blank line */
20872099
do {
20882100
char *comp_end, *hunk_begin;
20892101
char *tptr = temp;
@@ -2100,7 +2112,8 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int
21002112
}
21012113

21022114
if (first_field && bptr == line_end) {
2103-
add_next_index_null(return_value);
2115+
zend_array_destroy(values);
2116+
values = NULL;
21042117
break;
21052118
}
21062119
first_field = false;
@@ -2298,13 +2311,18 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int
22982311

22992312
/* 3. Now pass our field back to php */
23002313
*comp_end = '\0';
2301-
add_next_index_stringl(return_value, temp, comp_end - temp);
2314+
2315+
zval z_tmp;
2316+
ZVAL_STRINGL(&z_tmp, temp, comp_end - temp);
2317+
zend_hash_next_index_insert(values, &z_tmp);
23022318
} while (inc_len > 0);
23032319

23042320
efree(temp);
23052321
if (stream) {
23062322
efree(buf);
23072323
}
2324+
2325+
return values;
23082326
}
23092327
/* }}} */
23102328

‎ext/standard/file.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ PHPAPI void php_flock_common(php_stream *stream, zend_long operation, uint32_t o
4848
zval *wouldblock, zval *return_value);
4949

5050
#define PHP_CSV_NO_ESCAPE EOF
51-
PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int escape_char, size_t buf_len, char *buf, zval *return_value);
51+
PHPAPI HashTable *php_bc_fgetcsv_empty_line(void);
52+
PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int escape_char, size_t buf_len, char *buf);
5253
PHPAPI ssize_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, int escape_char, zend_string *eol_str);
5354

5455
#define META_DEF_BUFSIZE 8192

‎ext/standard/string.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -5253,7 +5253,11 @@ PHP_FUNCTION(str_getcsv)
52535253
esc = esc_len ? (unsigned char) esc_str[0] : PHP_CSV_NO_ESCAPE;
52545254
}
52555255

5256-
php_fgetcsv(NULL, delim, enc, esc, ZSTR_LEN(str), ZSTR_VAL(str), return_value);
5256+
HashTable *values = php_fgetcsv(NULL, delim, enc, esc, ZSTR_LEN(str), ZSTR_VAL(str));
5257+
if (values == NULL) {
5258+
values = php_bc_fgetcsv_empty_line();
5259+
}
5260+
RETURN_ARR(values);
52575261
}
52585262
/* }}} */
52595263

0 commit comments

Comments
 (0)
Please sign in to comment.