From: Greg Beaver Date: Thu, 13 Dec 2007 05:22:06 +0000 (+0000) Subject: new test X-Git-Tag: RELEASE_2_0_0a1~1191 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3b356d5ed8c171592e11c4c6cdf306959576324b;p=php new test now, SplDirectoryIterator can be used directly with Phar->buildFromIterator() in order to populate the files in a phar archive. When combined with a RegexIterator and other filters, it becomes very easy to create a phar archive with 1 line of code [DOC] --- diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index a9980f252e..4ac637dcf7 100755 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -310,6 +310,7 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) { zval **value; zend_uchar key_type; + zend_bool is_splfileinfo = 0; ulong int_key; struct _t { phar_archive_object *p; @@ -318,11 +319,11 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) 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; @@ -334,27 +335,70 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* 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)) { @@ -374,14 +418,18 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) #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; } @@ -389,14 +437,18 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) 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 { @@ -408,7 +460,9 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) 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); diff --git a/ext/phar/tests/phar_buildfromiterator8.phpt b/ext/phar/tests/phar_buildfromiterator8.phpt new file mode 100644 index 0000000000..a48b0404fb --- /dev/null +++ b/ext/phar/tests/phar_buildfromiterator8.phpt @@ -0,0 +1,94 @@ +--TEST-- +Phar::buildFromIterator() iterator, SplFileInfo as current +--SKIPIF-- + +--INI-- +phar.require_hash=0 +phar.readonly=0 +--FILE-- +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-- + +--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===