{
zval **value;
zend_uchar key_type;
+ zend_bool is_splfileinfo = 0;
ulong int_key;
struct _t {
phar_archive_object *p;
uint l;
zval *ret;
} *p_obj = (struct _t*) puser;
- uint str_key_len, base_len = p_obj->l;
+ uint str_key_len, base_len = p_obj->l, fname_len;
phar_entry_data *data;
php_stream *fp;
long contents_len;
- char *fname, *error, *str_key, *base = p_obj->b, *opened, *save;
+ char *fname, *error, *str_key, *base = p_obj->b, *opened, *save = NULL;
zend_class_entry *ce = p_obj->c;
phar_archive_object *phar_obj = p_obj->p;
/* failure in get_current_data */
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned no value", ce->name);
}
- if (Z_TYPE_PP(value) != IS_STRING) {
- zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned an invalid value (must return a string)", ce->name);
- return ZEND_HASH_APPLY_STOP;
+ switch (Z_TYPE_PP(value)) {
+ case IS_STRING :
+ break;
+ case IS_OBJECT :
+ if (instanceof_function(Z_OBJCE_PP(value), spl_ce_SplFileInfo)) {
+ char *test;
+ zval dummy;
+ spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(*value TSRMLS_CC);
+
+ if (!base_len) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Iterator %s returns an SplFileInfo object, so base directory must be specified", ce->name);
+ return ZEND_HASH_APPLY_STOP;
+ }
+ switch (intern->type) {
+ case SPL_FS_DIR:
+ fname_len = spprintf(&fname, 0, "%s%c%s", intern->path, DEFAULT_SLASH, intern->u.dir.entry.d_name);
+ php_stat(fname, fname_len, FS_IS_DIR, &dummy TSRMLS_CC);
+ if (Z_BVAL(dummy)) {
+ /* ignore directories */
+ efree(fname);
+ return ZEND_HASH_APPLY_KEEP;
+ }
+ test = expand_filepath(fname, test TSRMLS_CC);
+ if (test) {
+ efree(fname);
+ fname = test;
+ fname_len = strlen(fname);
+ }
+ save = fname;
+ is_splfileinfo = 1;
+ goto phar_spl_fileinfo;
+ case SPL_FS_INFO:
+ case SPL_FS_FILE:
+ return ZEND_HASH_APPLY_KEEP;
+ }
+ }
+ /* fall-through */
+ default :
+ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned an invalid value (must return a string)", ce->name);
+ return ZEND_HASH_APPLY_STOP;
}
fname = Z_STRVAL_PP(value);
+ fname_len = Z_STRLEN_PP(value);
+phar_spl_fileinfo:
if (base_len) {
if (strstr(fname, base)) {
- str_key_len = Z_STRLEN_PP(value) - base_len;
+ str_key_len = fname_len - base_len;
if (str_key_len <= 0) {
- efree(save);
+ if (save) {
+ efree(save);
+ }
return ZEND_HASH_APPLY_KEEP;
}
str_key = fname + base_len;
} else {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned a path \"%s\" that is not in the base directory \"%s\"", ce->name, fname, base);
- efree(save);
+ if (save) {
+ efree(save);
+ }
return ZEND_HASH_APPLY_STOP;
}
- } else {
+ } else {
if (iter->funcs->get_current_key) {
key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
if (EG(exception)) {
#if PHP_MAJOR_VERSION < 6
if (PG(safe_mode) && (!php_checkuid(fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned a path \"%s\" that safe mode prevents opening", ce->name, fname);
- efree(save);
+ if (save) {
+ efree(save);
+ }
return ZEND_HASH_APPLY_STOP;
}
#endif
if (php_check_open_basedir(fname TSRMLS_CC)) {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned a path \"%s\" that open_basedir prevents opening", ce->name, fname);
- efree(save);
+ if (save) {
+ efree(save);
+ }
return ZEND_HASH_APPLY_STOP;
}
fp = php_stream_open_wrapper(fname, "rb", STREAM_MUST_SEEK|0, &opened);
if (!fp) {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned a file that could not be opened \"%s\"", ce->name, fname);
- efree(save);
+ if (save) {
+ efree(save);
+ }
return ZEND_HASH_APPLY_STOP;
}
if (!(data = phar_get_or_create_entry_data(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len, str_key, str_key_len, "w+b", &error TSRMLS_CC))) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s cannot be created: %s", str_key, error);
efree(error);
- efree(save);
+ if (save) {
+ efree(save);
+ }
php_stream_close(fp);
return ZEND_HASH_APPLY_STOP;
} else {
php_stream_close(fp);
add_assoc_string(p_obj->ret, str_key, opened, 0);
- efree(save);
+ if (save) {
+ efree(save);
+ }
data->internal_file->compressed_filesize = data->internal_file->uncompressed_filesize = contents_len;
phar_entry_delref(data TSRMLS_CC);
--- /dev/null
+--TEST--
+Phar::buildFromIterator() iterator, SplFileInfo as current
+--SKIPIF--
+<?php if (!extension_loaded("phar")) print "skip"; ?>
+--INI--
+phar.require_hash=0
+phar.readonly=0
+--FILE--
+<?php
+try {
+ chdir(dirname(__FILE__));
+ $phar = new Phar(dirname(__FILE__) . '/buildfromiterator.phar');
+ var_dump($phar->buildFromIterator(new RegexIterator(new DirectoryIterator('.'), '/^\d{0,3}\.phpt\\z|^\.\\z|^\.\.\\z/'), dirname(__FILE__) . DIRECTORY_SEPARATOR));
+} catch (Exception $e) {
+ var_dump(get_class($e));
+ echo $e->getMessage() . "\n";
+}
+?>
+===DONE===
+--CLEAN--
+<?php
+unlink(dirname(__FILE__) . '/buildfromiterator.phar');
+__HALT_COMPILER();
+?>
+--EXPECT--
+array(33) {
+ ["001.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/001.phpt"
+ ["002.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/002.phpt"
+ ["003.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/003.phpt"
+ ["004.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/004.phpt"
+ ["005.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/005.phpt"
+ ["006.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/006.phpt"
+ ["007.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/007.phpt"
+ ["008.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/008.phpt"
+ ["009.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/009.phpt"
+ ["010.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/010.phpt"
+ ["011.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/011.phpt"
+ ["012.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/012.phpt"
+ ["013.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/013.phpt"
+ ["014.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/014.phpt"
+ ["015.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/015.phpt"
+ ["016.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/016.phpt"
+ ["017.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/017.phpt"
+ ["018.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/018.phpt"
+ ["019.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/019.phpt"
+ ["020.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/020.phpt"
+ ["021.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/021.phpt"
+ ["022.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/022.phpt"
+ ["023.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/023.phpt"
+ ["024.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/024.phpt"
+ ["025.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/025.phpt"
+ ["026.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/026.phpt"
+ ["027.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/027.phpt"
+ ["028.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/028.phpt"
+ ["029.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/029.phpt"
+ ["030.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/030.phpt"
+ ["031.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/031.phpt"
+ ["032.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/032.phpt"
+ ["033.phpt"]=>
+ string(51) "/home/cellog/workspace/php5/ext/phar/tests/033.phpt"
+}
+===DONE===