@@ -93,7 +93,7 @@ static inline spl_filesystem_object* spl_filesystem_iterator_to_object(spl_files
93
93
static void spl_filesystem_file_free_line (spl_filesystem_object * intern ) /* {{{ */
94
94
{
95
95
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 );
97
97
intern -> u .file .current_line = NULL ;
98
98
}
99
99
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
1884
1884
}
1885
1885
1886
1886
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 ();
1889
1888
} else {
1890
1889
if (!csv && SPL_HAS_FLAG (intern -> flags , SPL_FILE_OBJECT_DROP_NEW_LINE )) {
1891
1890
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
1897
1896
}
1898
1897
}
1899
1898
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 ) ;
1902
1901
}
1903
1902
intern -> u .file .current_line_num += line_add ;
1904
1903
@@ -1911,14 +1910,18 @@ static inline zend_result spl_filesystem_file_read(spl_filesystem_object *intern
1911
1910
return spl_filesystem_file_read_ex (intern , silent , line_add , csv );
1912
1911
}
1913
1912
1914
- static bool is_line_empty (spl_filesystem_object * intern )
1913
+ static bool is_line_empty (const spl_filesystem_object * intern )
1915
1914
{
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
+ );
1922
1925
}
1923
1926
1924
1927
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
1930
1933
}
1931
1934
} while (is_line_empty (intern ) && SPL_HAS_FLAG (intern -> flags , SPL_FILE_OBJECT_SKIP_EMPTY ));
1932
1935
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 );
1935
1941
1936
1942
if (!Z_ISUNDEF (intern -> u .file .current_zval )) {
1937
1943
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
1983
1989
intern -> u .file .current_line_num ++ ;
1984
1990
}
1985
1991
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 ));
1988
1993
zval_ptr_dtor (& retval );
1989
1994
return SUCCESS ;
1990
1995
} else {
@@ -2159,7 +2164,7 @@ PHP_METHOD(SplFileObject, fgets)
2159
2164
if (spl_filesystem_file_read_ex (intern , /* silent */ false, /* line_add */ 1 , /* csv */ false) == FAILURE ) {
2160
2165
RETURN_THROWS ();
2161
2166
}
2162
- RETURN_STRINGL (intern -> u .file .current_line , intern -> u . file . current_line_len );
2167
+ RETURN_STR_COPY (intern -> u .file .current_line );
2163
2168
} /* }}} */
2164
2169
2165
2170
/* {{{ Return current line from file */
@@ -2177,7 +2182,7 @@ PHP_METHOD(SplFileObject, current)
2177
2182
spl_filesystem_file_read_line (ZEND_THIS , intern , true);
2178
2183
}
2179
2184
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 );
2181
2186
} else if (!Z_ISUNDEF (intern -> u .file .current_zval )) {
2182
2187
ZEND_ASSERT (!Z_ISREF (intern -> u .file .current_zval ));
2183
2188
ZEND_ASSERT (Z_TYPE (intern -> u .file .current_zval ) == IS_ARRAY );
@@ -2575,7 +2580,7 @@ PHP_METHOD(SplFileObject, fpassthru)
2575
2580
/* {{{ Implements a mostly ANSI compatible fscanf() */
2576
2581
PHP_METHOD (SplFileObject , fscanf )
2577
2582
{
2578
- int result , num_varargs = 0 ;
2583
+ uint32_t num_varargs = 0 ;
2579
2584
zend_string * format_str ;
2580
2585
zval * varargs = NULL ;
2581
2586
spl_filesystem_object * intern = spl_filesystem_from_obj (Z_OBJ_P (ZEND_THIS ));
@@ -2591,7 +2596,7 @@ PHP_METHOD(SplFileObject, fscanf)
2591
2596
RETURN_THROWS ();
2592
2597
}
2593
2598
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 );
2595
2600
2596
2601
if (SCAN_ERROR_WRONG_PARAM_COUNT == result ) {
2597
2602
WRONG_PARAM_COUNT ;
@@ -2740,7 +2745,7 @@ PHP_METHOD(SplFileObject, __toString)
2740
2745
}
2741
2746
}
2742
2747
2743
- RETURN_STRINGL (intern -> u .file .current_line , intern -> u . file . current_line_len );
2748
+ RETURN_STR_COPY (intern -> u .file .current_line );
2744
2749
}
2745
2750
2746
2751
/* {{{ PHP_MINIT_FUNCTION(spl_directory) */
0 commit comments