Skip to content

Commit f296cba

Browse files
committed
ext/spl: Convert current_line to a zend_string*
1 parent bb4491a commit f296cba

File tree

2 files changed

+27
-23
lines changed

2 files changed

+27
-23
lines changed

ext/spl/spl_directory.c

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static inline spl_filesystem_object* spl_filesystem_iterator_to_object(spl_files
9393
static void spl_filesystem_file_free_line(spl_filesystem_object *intern) /* {{{ */
9494
{
9595
if (intern->u.file.current_line) {
96-
efree(intern->u.file.current_line);
96+
zend_string_release_ex(intern->u.file.current_line, /* persistent */ false);
9797
intern->u.file.current_line = NULL;
9898
}
9999
if (!Z_ISUNDEF(intern->u.file.current_zval)) {
@@ -1884,8 +1884,7 @@ static zend_result spl_filesystem_file_read_ex(spl_filesystem_object *intern, bo
18841884
}
18851885

18861886
if (!buf) {
1887-
intern->u.file.current_line = estrdup("");
1888-
intern->u.file.current_line_len = 0;
1887+
intern->u.file.current_line = ZSTR_EMPTY_ALLOC();
18891888
} else {
18901889
if (!csv && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)) {
18911890
if (line_len > 0 && buf[line_len - 1] == '\n') {
@@ -1897,8 +1896,8 @@ static zend_result spl_filesystem_file_read_ex(spl_filesystem_object *intern, bo
18971896
}
18981897
}
18991898

1900-
intern->u.file.current_line = buf;
1901-
intern->u.file.current_line_len = line_len;
1899+
intern->u.file.current_line = zend_string_init(buf, line_len, /* persistent */ false);
1900+
efree(buf);
19021901
}
19031902
intern->u.file.current_line_num += line_add;
19041903

@@ -1911,14 +1910,18 @@ static inline zend_result spl_filesystem_file_read(spl_filesystem_object *intern
19111910
return spl_filesystem_file_read_ex(intern, silent, line_add, csv);
19121911
}
19131912

1914-
static bool is_line_empty(spl_filesystem_object *intern)
1913+
static bool is_line_empty(const spl_filesystem_object *intern)
19151914
{
1916-
char *current_line = intern->u.file.current_line;
1917-
size_t current_line_len = intern->u.file.current_line_len;
1918-
return current_line_len == 0
1919-
|| ((SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)
1920-
&& ((current_line_len == 1 && current_line[0] == '\n')
1921-
|| (current_line_len == 2 && current_line[0] == '\r' && current_line[1] == '\n'))));
1915+
const char *current_line = ZSTR_VAL(intern->u.file.current_line);
1916+
size_t current_line_len = ZSTR_LEN(intern->u.file.current_line);
1917+
return current_line_len == 0 || (
1918+
SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)
1919+
&& SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)
1920+
&& (
1921+
(current_line_len == 1 && current_line[0] == '\n')
1922+
|| (current_line_len == 2 && current_line[0] == '\r' && current_line[1] == '\n')
1923+
)
1924+
);
19221925
}
19231926

19241927
static zend_result spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, int escape, zval *return_value, bool silent) /* {{{ */
@@ -1930,8 +1933,11 @@ static zend_result spl_filesystem_file_read_csv(spl_filesystem_object *intern, c
19301933
}
19311934
} while (is_line_empty(intern) && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_SKIP_EMPTY));
19321935

1933-
size_t buf_len = intern->u.file.current_line_len;
1934-
char *buf = estrndup(intern->u.file.current_line, buf_len);
1936+
/* We need to duplicate the current line content as php_fgetcsv() will free it.
1937+
* This is because it might reach the end of the line when it's in an enclosure and
1938+
* thus must fetch the next line from the stream */
1939+
size_t buf_len = ZSTR_LEN(intern->u.file.current_line);
1940+
char *buf = estrndup(ZSTR_VAL(intern->u.file.current_line), buf_len);
19351941

19361942
if (!Z_ISUNDEF(intern->u.file.current_zval)) {
19371943
zval_ptr_dtor(&intern->u.file.current_zval);
@@ -1983,8 +1989,7 @@ static zend_result spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesys
19831989
intern->u.file.current_line_num++;
19841990
}
19851991
spl_filesystem_file_free_line(intern);
1986-
intern->u.file.current_line = estrndup(Z_STRVAL(retval), Z_STRLEN(retval));
1987-
intern->u.file.current_line_len = Z_STRLEN(retval);
1992+
intern->u.file.current_line = zend_string_copy(Z_STR(retval));
19881993
zval_ptr_dtor(&retval);
19891994
return SUCCESS;
19901995
} else {
@@ -2159,7 +2164,7 @@ PHP_METHOD(SplFileObject, fgets)
21592164
if (spl_filesystem_file_read_ex(intern, /* silent */ false, /* line_add */ 1, /* csv */ false) == FAILURE) {
21602165
RETURN_THROWS();
21612166
}
2162-
RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len);
2167+
RETURN_STR_COPY(intern->u.file.current_line);
21632168
} /* }}} */
21642169

21652170
/* {{{ Return current line from file */
@@ -2177,7 +2182,7 @@ PHP_METHOD(SplFileObject, current)
21772182
spl_filesystem_file_read_line(ZEND_THIS, intern, true);
21782183
}
21792184
if (intern->u.file.current_line && (!SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || Z_ISUNDEF(intern->u.file.current_zval))) {
2180-
RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len);
2185+
RETURN_STR_COPY(intern->u.file.current_line);
21812186
} else if (!Z_ISUNDEF(intern->u.file.current_zval)) {
21822187
ZEND_ASSERT(!Z_ISREF(intern->u.file.current_zval));
21832188
ZEND_ASSERT(Z_TYPE(intern->u.file.current_zval) == IS_ARRAY);
@@ -2575,7 +2580,7 @@ PHP_METHOD(SplFileObject, fpassthru)
25752580
/* {{{ Implements a mostly ANSI compatible fscanf() */
25762581
PHP_METHOD(SplFileObject, fscanf)
25772582
{
2578-
int result, num_varargs = 0;
2583+
uint32_t num_varargs = 0;
25792584
zend_string *format_str;
25802585
zval *varargs= NULL;
25812586
spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS));
@@ -2591,7 +2596,7 @@ PHP_METHOD(SplFileObject, fscanf)
25912596
RETURN_THROWS();
25922597
}
25932598

2594-
result = php_sscanf_internal(intern->u.file.current_line, ZSTR_VAL(format_str), num_varargs, varargs, 0, return_value);
2599+
int result = php_sscanf_internal(ZSTR_VAL(intern->u.file.current_line), ZSTR_VAL(format_str), (int)num_varargs, varargs, 0, return_value);
25952600

25962601
if (SCAN_ERROR_WRONG_PARAM_COUNT == result) {
25972602
WRONG_PARAM_COUNT;
@@ -2740,7 +2745,7 @@ PHP_METHOD(SplFileObject, __toString)
27402745
}
27412746
}
27422747

2743-
RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len);
2748+
RETURN_STR_COPY(intern->u.file.current_line);
27442749
}
27452750

27462751
/* {{{ PHP_MINIT_FUNCTION(spl_directory) */

ext/spl/spl_directory.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ struct _spl_filesystem_object {
7575
zval *zcontext;
7676
zend_string *open_mode;
7777
zval current_zval;
78-
char *current_line;
79-
size_t current_line_len;
78+
zend_string *current_line;
8079
size_t max_line_len;
8180
zend_long current_line_num;
8281
zval zresource;

0 commit comments

Comments
 (0)