Re: Re: Bug 67072 resolution for 5.4/5.5
| From: | Remi Collet | Date: | Tue, 24 Jun 2014 07:39:16 +0000 |
| Subject: | Re: Re: Bug 67072 resolution for 5.4/5.5 | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 12 13 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-75053@lists.php.net to get a copy of this message | ||
Le 23/06/2014 19:41, Stas Malyshev a écrit :
> Hi!
>
>> Minimal reproducer:
>>
>> <?php
>> class FooFile extends SplFileInfo {
>> }
>> $str = 'O:7:"FooFile":0:{}';
>> var_dump(unserialize($str));
>> ?>
>
> I'm afraid here we can't do much - SplFileInfo is one of the classes
> that it is unsafe to instantiate this way. It's what original 67072 was
> about and I don't think it's safe to leave it this way, since at best it
> can crash any code that uses unserialize() on external data, at worst
> you got RCE.
I think the segfault have to be fixed in spl.
And if we plan to allow newInstanceArgWithoutConstructor() for internal
classes this is mandatory.
See attached patch (quickly written, just for test)
So we can allow "O:.." (perhaps only for empty data used in the
phpunit/doctrine hack, => strlen(*p)<=1)
Running:
echo
unserialize('O:13:"SplFileObject":1:{s:9:"*filename";s:15:"/home/flag/flag";}');
echo unserialize('O:13:"SplFileObject":0:{}');
Warning: Erroneous data format for unserializing 'SplFileObject' ...
Fatal error: SplFileObject::__toString(): Object not initialized ...
Remi.
diff -up ext/spl/spl_directory.c.prev ext/spl/spl_directory.c --- ext/spl/spl_directory.c.prev 2014-06-24 09:24:36.728584770 +0200 +++ ext/spl/spl_directory.c 2014-06-24 09:27:31.632334073 +0200 @@ -46,6 +46,12 @@ #define SPL_HAS_FLAG(flags, test_flag) ((flags & test_flag) ? 1 : 0) +#define SPL_CHECK_TYPE(_type) do {\ + if (intern->type != _type) { \ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Object not initialized"); \ + } \ + } while (0) + /* declare the class handlers */ static zend_object_handlers spl_filesystem_object_handlers; /* includes handler to validate object state when retrieving methods */ @@ -151,7 +157,7 @@ static zend_object_value spl_filesystem_ intern = emalloc(sizeof(spl_filesystem_object)); memset(intern, 0, sizeof(spl_filesystem_object)); - /* intern->type = SPL_FS_INFO; done by set 0 */ + intern->type = SPL_FS_INFO; intern->file_class = spl_ce_SplFileObject; intern->info_class = spl_ce_SplFileInfo; if (obj) *obj = intern; @@ -753,6 +759,7 @@ SPL_METHOD(DirectoryIterator, rewind) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); intern->u.dir.index = 0; if (intern->u.dir.dirp) { php_stream_rewinddir(intern->u.dir.dirp); @@ -801,6 +808,7 @@ SPL_METHOD(DirectoryIterator, next) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); intern->u.dir.index++; do { spl_filesystem_dir_read(intern TSRMLS_CC); @@ -824,6 +832,7 @@ SPL_METHOD(DirectoryIterator, seek) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (intern->u.dir.index > pos) { /* we first rewind */ zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_rewind, "rewind", &retval); @@ -861,6 +870,7 @@ SPL_METHOD(DirectoryIterator, valid) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); RETURN_BOOL(intern->u.dir.entry.d_name[0] != '\0'); } /* }}} */ @@ -913,6 +923,7 @@ SPL_METHOD(DirectoryIterator, getFilenam return; } + SPL_CHECK_TYPE(SPL_FS_DIR); RETURN_STRING(intern->u.dir.entry.d_name, 1); } /* }}} */ @@ -972,6 +983,7 @@ SPL_METHOD(DirectoryIterator, getExtensi return; } + SPL_CHECK_TYPE(SPL_FS_DIR); php_basename(intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name), NULL, 0, &fname, &flen TSRMLS_CC); p = zend_memrchr(fname, '.', flen); @@ -1031,6 +1043,7 @@ SPL_METHOD(DirectoryIterator, getBasenam return; } + SPL_CHECK_TYPE(SPL_FS_DIR); php_basename(intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name), suffix, slen, &fname, &flen TSRMLS_CC); RETURN_STRINGL(fname, flen, 0); @@ -1067,6 +1080,7 @@ SPL_METHOD(FilesystemIterator, key) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (SPL_FILE_DIR_KEY(intern, SPL_FILE_DIR_KEY_AS_FILENAME)) { RETURN_STRING(intern->u.dir.entry.d_name, 1); } else { @@ -1086,6 +1100,7 @@ SPL_METHOD(FilesystemIterator, current) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (SPL_FILE_DIR_CURRENT(intern, SPL_FILE_DIR_CURRENT_AS_PATHNAME)) { spl_filesystem_object_get_file_name(intern TSRMLS_CC); RETURN_STRINGL(intern->file_name, intern->file_name_len, 1); @@ -1109,6 +1124,7 @@ SPL_METHOD(DirectoryIterator, isDot) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); RETURN_BOOL(spl_filesystem_is_dot(intern->u.dir.entry.d_name)); } /* }}} */ @@ -1142,7 +1158,7 @@ SPL_METHOD(SplFileInfo, __construct) zend_restore_error_handling(&error_handling TSRMLS_CC); - /* intern->type = SPL_FS_INFO; already set */ + intern->type = SPL_FS_INFO; } /* }}} */ @@ -1445,6 +1461,7 @@ SPL_METHOD(FilesystemIterator, rewind) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); intern->u.dir.index = 0; if (intern->u.dir.dirp) { php_stream_rewinddir(intern->u.dir.dirp); @@ -1465,6 +1482,7 @@ SPL_METHOD(FilesystemIterator, getFlags) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); RETURN_LONG(intern->flags & (SPL_FILE_DIR_KEY_MODE_MASK | SPL_FILE_DIR_CURRENT_MODE_MASK | SPL_FILE_DIR_OTHERS_MASK)); } /* }}} */ @@ -1493,6 +1511,7 @@ SPL_METHOD(RecursiveDirectoryIterator, h if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &allow_links) == FAILURE) { return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (spl_filesystem_is_invalid_or_dot(intern->u.dir.entry.d_name)) { RETURN_FALSE; } else { @@ -1521,6 +1540,7 @@ SPL_METHOD(RecursiveDirectoryIterator, g return; } + SPL_CHECK_TYPE(SPL_FS_DIR); spl_filesystem_object_get_file_name(intern TSRMLS_CC); if (SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_CURRENT_AS_PATHNAME)) { @@ -1560,6 +1580,7 @@ SPL_METHOD(RecursiveDirectoryIterator, g return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (intern->u.dir.sub_path) { RETURN_STRINGL(intern->u.dir.sub_path, intern->u.dir.sub_path_len, 1); } else { @@ -1581,6 +1602,7 @@ SPL_METHOD(RecursiveDirectoryIterator, g return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (intern->u.dir.sub_path) { len = spprintf(&sub_name, 0, "%s%c%s", intern->u.dir.sub_path, slash, intern->u.dir.entry.d_name); RETURN_STRINGL(sub_name, len, 0); @@ -2151,6 +2173,7 @@ static int spl_filesystem_file_call(spl_ zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Internal error, function '%s' not found. Please report", #func_name); \ return; \ } \ + SPL_CHECK_TYPE(SPL_FS_FILE); \ spl_filesystem_file_call(intern, func_ptr, pass_num_args, return_value, arg2 TSRMLS_CC); \ } /* }}} */ @@ -2384,6 +2407,7 @@ SPL_METHOD(SplFileObject, rewind) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC); } /* }}} */ @@ -2397,6 +2421,7 @@ SPL_METHOD(SplFileObject, eof) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); RETURN_BOOL(php_stream_eof(intern->u.file.stream)); } /* }}} */ @@ -2410,6 +2435,7 @@ SPL_METHOD(SplFileObject, valid) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { RETURN_BOOL(intern->u.file.current_line || intern->u.file.current_zval); } else { @@ -2427,6 +2453,7 @@ SPL_METHOD(SplFileObject, fgets) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); if (spl_filesystem_file_read(intern, 0 TSRMLS_CC) == FAILURE) { RETURN_FALSE; } @@ -2442,7 +2469,7 @@ SPL_METHOD(SplFileObject, current) if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_CHECK_TYPE(SPL_FS_FILE); if (!intern->u.file.current_line && !intern->u.file.current_zval) { spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC); } @@ -2464,6 +2491,7 @@ SPL_METHOD(SplFileObject, key) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); /* Do not read the next line to support correct counting with fgetc() if (!intern->current_line) { spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC); @@ -2481,6 +2509,7 @@ SPL_METHOD(SplFileObject, next) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_free_line(intern TSRMLS_CC); if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC); @@ -2528,7 +2557,8 @@ SPL_METHOD(SplFileObject, setMaxLineLen) zend_throw_exception_ex(spl_ce_DomainException, 0 TSRMLS_CC, "Maximum line length must be greater than or equal zero"); return; } - + SPL_CHECK_TYPE(SPL_FS_FILE); + intern->u.file.max_line_len = max_len; } /* }}} */ @@ -2542,6 +2572,7 @@ SPL_METHOD(SplFileObject, getMaxLineLen) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); RETURN_LONG((long)intern->u.file.max_line_len); } /* }}} */ @@ -2611,6 +2642,7 @@ SPL_METHOD(SplFileObject, fgetcsv) case 0: break; } + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_read_csv(intern, delimiter, enclosure, escape, return_value TSRMLS_CC); } } @@ -2647,6 +2679,7 @@ SPL_METHOD(SplFileObject, fputcsv) case 0: break; } + SPL_CHECK_TYPE(SPL_FS_FILE); ret = php_fputcsv(intern->u.file.stream, fields, delimiter, enclosure, escape TSRMLS_CC); RETURN_LONG(ret); } @@ -2689,6 +2722,7 @@ SPL_METHOD(SplFileObject, setCsvControl) case 0: break; } + SPL_CHECK_TYPE(SPL_FS_FILE); intern->u.file.delimiter = delimiter; intern->u.file.enclosure = enclosure; intern->u.file.escape = escape; @@ -2703,6 +2737,7 @@ SPL_METHOD(SplFileObject, getCsvControl) spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); char delimiter[2], enclosure[2]; + SPL_CHECK_TYPE(SPL_FS_FILE); array_init(return_value); delimiter[0] = intern->u.file.delimiter; @@ -2726,6 +2761,7 @@ SPL_METHOD(SplFileObject, fflush) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_CHECK_TYPE(SPL_FS_FILE); RETURN_BOOL(!php_stream_flush(intern->u.file.stream)); } /* }}} */ @@ -2734,6 +2770,7 @@ SPL_METHOD(SplFileObject, fflush) SPL_METHOD(SplFileObject, ftell) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_CHECK_TYPE(SPL_FS_FILE); long ret = php_stream_tell(intern->u.file.stream); if (ret == -1) { @@ -2754,6 +2791,7 @@ SPL_METHOD(SplFileObject, fseek) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_free_line(intern TSRMLS_CC); RETURN_LONG(php_stream_seek(intern->u.file.stream, pos, whence)); } /* }}} */ @@ -2766,6 +2804,7 @@ SPL_METHOD(SplFileObject, fgetc) char buf[2]; int result; + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_free_line(intern TSRMLS_CC); result = php_stream_getc(intern->u.file.stream); @@ -2789,8 +2828,9 @@ SPL_METHOD(SplFileObject, fgetss) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zval *arg2 = NULL; - MAKE_STD_ZVAL(arg2); + SPL_CHECK_TYPE(SPL_FS_FILE); + MAKE_STD_ZVAL(arg2); if (intern->u.file.max_line_len > 0) { ZVAL_LONG(arg2, intern->u.file.max_line_len); } else { @@ -2811,6 +2851,7 @@ SPL_METHOD(SplFileObject, fpassthru) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_CHECK_TYPE(SPL_FS_FILE); RETURN_LONG(php_stream_passthru(intern->u.file.stream)); } /* }}} */ @@ -2820,6 +2861,7 @@ SPL_METHOD(SplFileObject, fscanf) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_free_line(intern TSRMLS_CC); intern->u.file.current_line_num++; @@ -2846,6 +2888,7 @@ SPL_METHOD(SplFileObject, fwrite) if (!str_len) { RETURN_LONG(0); } + SPL_CHECK_TYPE(SPL_FS_FILE); RETURN_LONG(php_stream_write(intern->u.file.stream, str, str_len)); } /* }}} */ @@ -2864,6 +2907,7 @@ SPL_METHOD(SplFileObject, fread) RETURN_FALSE; } + SPL_CHECK_TYPE(SPL_FS_FILE); Z_STRVAL_P(return_value) = emalloc(length + 1); Z_STRLEN_P(return_value) = php_stream_read(intern->u.file.stream, Z_STRVAL_P(return_value), length); @@ -2888,6 +2932,7 @@ SPL_METHOD(SplFileObject, ftruncate) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); if (!php_stream_truncate_supported(intern->u.file.stream)) { zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't truncate file %s", intern->file_name); RETURN_FALSE; @@ -2911,6 +2956,7 @@ SPL_METHOD(SplFileObject, seek) RETURN_FALSE; } + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC); while(intern->u.file.current_line_num < line_pos) { diff -up ext/spl/spl_directory.h.prev ext/spl/spl_directory.h --- ext/spl/spl_directory.h.prev 2014-06-24 09:24:41.303604369 +0200 +++ ext/spl/spl_directory.h 2014-06-24 09:20:21.505491639 +0200 @@ -35,7 +35,8 @@ extern PHPAPI zend_class_entry *spl_ce_S PHP_MINIT_FUNCTION(spl_directory); typedef enum { - SPL_FS_INFO, /* must be 0 */ + SPL_FS_NOTINITIALIZED, + SPL_FS_INFO, SPL_FS_DIR, SPL_FS_FILE } SPL_FS_OBJ_TYPE;
diff -up ext/spl/spl_directory.c.prev ext/spl/spl_directory.c --- ext/spl/spl_directory.c.prev 2014-06-24 09:24:36.728584770 +0200 +++ ext/spl/spl_directory.c 2014-06-24 09:27:31.632334073 +0200 @@ -46,6 +46,12 @@ #define SPL_HAS_FLAG(flags, test_flag) ((flags & test_flag) ? 1 : 0) +#define SPL_CHECK_TYPE(_type) do {\ + if (intern->type != _type) { \ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Object not initialized"); \ + } \ + } while (0) + /* declare the class handlers */ static zend_object_handlers spl_filesystem_object_handlers; /* includes handler to validate object state when retrieving methods */ @@ -151,7 +157,7 @@ static zend_object_value spl_filesystem_ intern = emalloc(sizeof(spl_filesystem_object)); memset(intern, 0, sizeof(spl_filesystem_object)); - /* intern->type = SPL_FS_INFO; done by set 0 */ + intern->type = SPL_FS_INFO; intern->file_class = spl_ce_SplFileObject; intern->info_class = spl_ce_SplFileInfo; if (obj) *obj = intern; @@ -753,6 +759,7 @@ SPL_METHOD(DirectoryIterator, rewind) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); intern->u.dir.index = 0; if (intern->u.dir.dirp) { php_stream_rewinddir(intern->u.dir.dirp); @@ -801,6 +808,7 @@ SPL_METHOD(DirectoryIterator, next) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); intern->u.dir.index++; do { spl_filesystem_dir_read(intern TSRMLS_CC); @@ -824,6 +832,7 @@ SPL_METHOD(DirectoryIterator, seek) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (intern->u.dir.index > pos) { /* we first rewind */ zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_rewind, "rewind", &retval); @@ -861,6 +870,7 @@ SPL_METHOD(DirectoryIterator, valid) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); RETURN_BOOL(intern->u.dir.entry.d_name[0] != '\0'); } /* }}} */ @@ -913,6 +923,7 @@ SPL_METHOD(DirectoryIterator, getFilenam return; } + SPL_CHECK_TYPE(SPL_FS_DIR); RETURN_STRING(intern->u.dir.entry.d_name, 1); } /* }}} */ @@ -972,6 +983,7 @@ SPL_METHOD(DirectoryIterator, getExtensi return; } + SPL_CHECK_TYPE(SPL_FS_DIR); php_basename(intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name), NULL, 0, &fname, &flen TSRMLS_CC); p = zend_memrchr(fname, '.', flen); @@ -1031,6 +1043,7 @@ SPL_METHOD(DirectoryIterator, getBasenam return; } + SPL_CHECK_TYPE(SPL_FS_DIR); php_basename(intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name), suffix, slen, &fname, &flen TSRMLS_CC); RETURN_STRINGL(fname, flen, 0); @@ -1067,6 +1080,7 @@ SPL_METHOD(FilesystemIterator, key) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (SPL_FILE_DIR_KEY(intern, SPL_FILE_DIR_KEY_AS_FILENAME)) { RETURN_STRING(intern->u.dir.entry.d_name, 1); } else { @@ -1086,6 +1100,7 @@ SPL_METHOD(FilesystemIterator, current) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (SPL_FILE_DIR_CURRENT(intern, SPL_FILE_DIR_CURRENT_AS_PATHNAME)) { spl_filesystem_object_get_file_name(intern TSRMLS_CC); RETURN_STRINGL(intern->file_name, intern->file_name_len, 1); @@ -1109,6 +1124,7 @@ SPL_METHOD(DirectoryIterator, isDot) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); RETURN_BOOL(spl_filesystem_is_dot(intern->u.dir.entry.d_name)); } /* }}} */ @@ -1142,7 +1158,7 @@ SPL_METHOD(SplFileInfo, __construct) zend_restore_error_handling(&error_handling TSRMLS_CC); - /* intern->type = SPL_FS_INFO; already set */ + intern->type = SPL_FS_INFO; } /* }}} */ @@ -1445,6 +1461,7 @@ SPL_METHOD(FilesystemIterator, rewind) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); intern->u.dir.index = 0; if (intern->u.dir.dirp) { php_stream_rewinddir(intern->u.dir.dirp); @@ -1465,6 +1482,7 @@ SPL_METHOD(FilesystemIterator, getFlags) return; } + SPL_CHECK_TYPE(SPL_FS_DIR); RETURN_LONG(intern->flags & (SPL_FILE_DIR_KEY_MODE_MASK | SPL_FILE_DIR_CURRENT_MODE_MASK | SPL_FILE_DIR_OTHERS_MASK)); } /* }}} */ @@ -1493,6 +1511,7 @@ SPL_METHOD(RecursiveDirectoryIterator, h if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &allow_links) == FAILURE) { return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (spl_filesystem_is_invalid_or_dot(intern->u.dir.entry.d_name)) { RETURN_FALSE; } else { @@ -1521,6 +1540,7 @@ SPL_METHOD(RecursiveDirectoryIterator, g return; } + SPL_CHECK_TYPE(SPL_FS_DIR); spl_filesystem_object_get_file_name(intern TSRMLS_CC); if (SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_CURRENT_AS_PATHNAME)) { @@ -1560,6 +1580,7 @@ SPL_METHOD(RecursiveDirectoryIterator, g return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (intern->u.dir.sub_path) { RETURN_STRINGL(intern->u.dir.sub_path, intern->u.dir.sub_path_len, 1); } else { @@ -1581,6 +1602,7 @@ SPL_METHOD(RecursiveDirectoryIterator, g return; } + SPL_CHECK_TYPE(SPL_FS_DIR); if (intern->u.dir.sub_path) { len = spprintf(&sub_name, 0, "%s%c%s", intern->u.dir.sub_path, slash, intern->u.dir.entry.d_name); RETURN_STRINGL(sub_name, len, 0); @@ -2151,6 +2173,7 @@ static int spl_filesystem_file_call(spl_ zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Internal error, function '%s' not found. Please report", #func_name); \ return; \ } \ + SPL_CHECK_TYPE(SPL_FS_FILE); \ spl_filesystem_file_call(intern, func_ptr, pass_num_args, return_value, arg2 TSRMLS_CC); \ } /* }}} */ @@ -2384,6 +2407,7 @@ SPL_METHOD(SplFileObject, rewind) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC); } /* }}} */ @@ -2397,6 +2421,7 @@ SPL_METHOD(SplFileObject, eof) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); RETURN_BOOL(php_stream_eof(intern->u.file.stream)); } /* }}} */ @@ -2410,6 +2435,7 @@ SPL_METHOD(SplFileObject, valid) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { RETURN_BOOL(intern->u.file.current_line || intern->u.file.current_zval); } else { @@ -2427,6 +2453,7 @@ SPL_METHOD(SplFileObject, fgets) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); if (spl_filesystem_file_read(intern, 0 TSRMLS_CC) == FAILURE) { RETURN_FALSE; } @@ -2442,7 +2469,7 @@ SPL_METHOD(SplFileObject, current) if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_CHECK_TYPE(SPL_FS_FILE); if (!intern->u.file.current_line && !intern->u.file.current_zval) { spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC); } @@ -2464,6 +2491,7 @@ SPL_METHOD(SplFileObject, key) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); /* Do not read the next line to support correct counting with fgetc() if (!intern->current_line) { spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC); @@ -2481,6 +2509,7 @@ SPL_METHOD(SplFileObject, next) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_free_line(intern TSRMLS_CC); if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC); @@ -2528,7 +2557,8 @@ SPL_METHOD(SplFileObject, setMaxLineLen) zend_throw_exception_ex(spl_ce_DomainException, 0 TSRMLS_CC, "Maximum line length must be greater than or equal zero"); return; } - + SPL_CHECK_TYPE(SPL_FS_FILE); + intern->u.file.max_line_len = max_len; } /* }}} */ @@ -2542,6 +2572,7 @@ SPL_METHOD(SplFileObject, getMaxLineLen) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); RETURN_LONG((long)intern->u.file.max_line_len); } /* }}} */ @@ -2611,6 +2642,7 @@ SPL_METHOD(SplFileObject, fgetcsv) case 0: break; } + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_read_csv(intern, delimiter, enclosure, escape, return_value TSRMLS_CC); } } @@ -2647,6 +2679,7 @@ SPL_METHOD(SplFileObject, fputcsv) case 0: break; } + SPL_CHECK_TYPE(SPL_FS_FILE); ret = php_fputcsv(intern->u.file.stream, fields, delimiter, enclosure, escape TSRMLS_CC); RETURN_LONG(ret); } @@ -2689,6 +2722,7 @@ SPL_METHOD(SplFileObject, setCsvControl) case 0: break; } + SPL_CHECK_TYPE(SPL_FS_FILE); intern->u.file.delimiter = delimiter; intern->u.file.enclosure = enclosure; intern->u.file.escape = escape; @@ -2703,6 +2737,7 @@ SPL_METHOD(SplFileObject, getCsvControl) spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); char delimiter[2], enclosure[2]; + SPL_CHECK_TYPE(SPL_FS_FILE); array_init(return_value); delimiter[0] = intern->u.file.delimiter; @@ -2726,6 +2761,7 @@ SPL_METHOD(SplFileObject, fflush) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_CHECK_TYPE(SPL_FS_FILE); RETURN_BOOL(!php_stream_flush(intern->u.file.stream)); } /* }}} */ @@ -2734,6 +2770,7 @@ SPL_METHOD(SplFileObject, fflush) SPL_METHOD(SplFileObject, ftell) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_CHECK_TYPE(SPL_FS_FILE); long ret = php_stream_tell(intern->u.file.stream); if (ret == -1) { @@ -2754,6 +2791,7 @@ SPL_METHOD(SplFileObject, fseek) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_free_line(intern TSRMLS_CC); RETURN_LONG(php_stream_seek(intern->u.file.stream, pos, whence)); } /* }}} */ @@ -2766,6 +2804,7 @@ SPL_METHOD(SplFileObject, fgetc) char buf[2]; int result; + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_free_line(intern TSRMLS_CC); result = php_stream_getc(intern->u.file.stream); @@ -2789,8 +2828,9 @@ SPL_METHOD(SplFileObject, fgetss) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zval *arg2 = NULL; - MAKE_STD_ZVAL(arg2); + SPL_CHECK_TYPE(SPL_FS_FILE); + MAKE_STD_ZVAL(arg2); if (intern->u.file.max_line_len > 0) { ZVAL_LONG(arg2, intern->u.file.max_line_len); } else { @@ -2811,6 +2851,7 @@ SPL_METHOD(SplFileObject, fpassthru) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_CHECK_TYPE(SPL_FS_FILE); RETURN_LONG(php_stream_passthru(intern->u.file.stream)); } /* }}} */ @@ -2820,6 +2861,7 @@ SPL_METHOD(SplFileObject, fscanf) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_free_line(intern TSRMLS_CC); intern->u.file.current_line_num++; @@ -2846,6 +2888,7 @@ SPL_METHOD(SplFileObject, fwrite) if (!str_len) { RETURN_LONG(0); } + SPL_CHECK_TYPE(SPL_FS_FILE); RETURN_LONG(php_stream_write(intern->u.file.stream, str, str_len)); } /* }}} */ @@ -2864,6 +2907,7 @@ SPL_METHOD(SplFileObject, fread) RETURN_FALSE; } + SPL_CHECK_TYPE(SPL_FS_FILE); Z_STRVAL_P(return_value) = emalloc(length + 1); Z_STRLEN_P(return_value) = php_stream_read(intern->u.file.stream, Z_STRVAL_P(return_value), length); @@ -2888,6 +2932,7 @@ SPL_METHOD(SplFileObject, ftruncate) return; } + SPL_CHECK_TYPE(SPL_FS_FILE); if (!php_stream_truncate_supported(intern->u.file.stream)) { zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't truncate file %s", intern->file_name); RETURN_FALSE; @@ -2911,6 +2956,7 @@ SPL_METHOD(SplFileObject, seek) RETURN_FALSE; } + SPL_CHECK_TYPE(SPL_FS_FILE); spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC); while(intern->u.file.current_line_num < line_pos) { diff -up ext/spl/spl_directory.h.prev ext/spl/spl_directory.h --- ext/spl/spl_directory.h.prev 2014-06-24 09:24:41.303604369 +0200 +++ ext/spl/spl_directory.h 2014-06-24 09:20:21.505491639 +0200 @@ -35,7 +35,8 @@ extern PHPAPI zend_class_entry *spl_ce_S PHP_MINIT_FUNCTION(spl_directory); typedef enum { - SPL_FS_INFO, /* must be 0 */ + SPL_FS_NOTINITIALIZED, + SPL_FS_INFO, SPL_FS_DIR, SPL_FS_FILE } SPL_FS_OBJ_TYPE;