@@ -93,7 +93,7 @@ static inline spl_filesystem_object* spl_filesystem_iterator_to_object(spl_files
9393static 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
19241927static 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() */
25762581PHP_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) */
0 commit comments