if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "ss|br", &filename, &filename_len, &mode, &mode_len, &use_include_path, &zcontext) == FAILURE) {
goto skip_phar;
}
- if (!use_include_path && !IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
+ if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://"))) {
char *arch, *entry, *fname;
int arch_len, entry_len, fname_len;
php_stream_context *context = NULL;
+ char *name;
+ phar_archive_data **pphar;
fname = zend_get_executed_filename(TSRMLS_C);
if (strncasecmp(fname, "phar://", 7)) {
goto skip_phar;
}
fname_len = strlen(fname);
- if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
- char *name, *old;
- phar_archive_data **pphar;
+ if (FAILURE == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
+ goto skip_phar;
+ }
- old = entry;
- entry = filename;
- /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
- entry_len = filename_len;
- if (strstr(entry, "://")) {
- efree(old);
+ efree(entry);
+ entry = filename;
+ /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
+ entry_len = filename_len;
+ /* retrieving a file defaults to within the current directory, so use this if possible */
+ if (FAILURE == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) {
+ efree(arch);
+ goto skip_phar;
+ }
+ if (use_include_path) {
+ if (!(entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) {
+ /* this file is not in the phar, use the original path */
efree(arch);
goto skip_phar;
+ } else {
+ name = entry;
}
- /* retrieving a file defaults to within the current directory, so use this if possible */
- if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) {
- if (use_include_path) {
- name = entry;
- if (!(entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) {
- /* this file is not in the phar, use the original path */
- efree(old);
- efree(arch);
- efree(name);
- goto skip_phar;
- }
- efree(old);
- name = entry;
- goto already_setup;
- } else {
- efree(old);
- entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
- if (!zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) {
- /* this file is not in the phar, use the original path */
- efree(entry);
- efree(arch);
- goto skip_phar;
- }
- }
- }
- /* auto-convert to phar:// */
- spprintf(&name, 4096, "phar://%s/%s", arch, entry);
- if (entry != filename) {
+ } else {
+ entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
+ if (!zend_hash_exists(&((*pphar)->manifest), entry + 1, entry_len - 1)) {
+ /* this file is not in the phar, use the original path */
efree(entry);
+ efree(arch);
+ goto skip_phar;
}
-already_setup:
- efree(arch);
- context = php_stream_context_from_zval(zcontext, 0);
- stream = php_stream_open_wrapper_ex(name, mode, 0 | REPORT_ERRORS, NULL, context);
- efree(name);
- if (stream == NULL) {
- RETURN_FALSE;
- }
- php_stream_to_zval(stream, return_value);
- if (zcontext) {
- zend_list_addref(Z_RESVAL_P(zcontext));
- }
- return;
+ /* auto-convert to phar:// */
+ spprintf(&name, 4096, "phar://%s%s", arch, entry);
+ efree(entry);
+ }
+
+ efree(arch);
+ context = php_stream_context_from_zval(zcontext, 0);
+ stream = php_stream_open_wrapper_ex(name, mode, 0 | REPORT_ERRORS, NULL, context);
+ efree(name);
+ if (stream == NULL) {
+ RETURN_FALSE;
+ }
+ php_stream_to_zval(stream, return_value);
+ if (zcontext) {
+ zend_list_addref(Z_RESVAL_P(zcontext));
}
+ return;
}
skip_phar:
PHAR_G(orig_fopen)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
--- /dev/null
+--TEST--
+Phar: test fopen() interception
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip");?>
+--INI--
+phar.require_hash=1
+phar.readonly=0
+--FILE--
+<?php
+Phar::interceptFileFuncs();
+$a = fopen(__FILE__, 'rb'); // this satisfies 1 line of code coverage
+fclose($a);
+$a = fopen(); // this satisfies another line of code coverage
+
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$a = new Phar($fname);
+$a['index.php'] = '<?php
+$a = fopen("dir/file1.txt", "r");
+echo fread($a, 2);
+fclose($a);
+$a = fopen("file1.txt", "r", true);
+echo fread($a, 2);
+fclose($a);
+$a = fopen("notfound.txt", "r", true);
+?>';
+$a['dir/file1.txt'] = 'hi';
+$a['dir/file2.txt'] = 'hi2';
+$a['dir/file3.txt'] = 'hi3';
+$a->setStub('<?php
+set_include_path("phar://" . __FILE__ . "/dir" . PATH_SEPARATOR . "phar://" . __FILE__);
+include "index.php";
+__HALT_COMPILER();');
+include $fname;
+?>
+===DONE===
+--CLEAN--
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
+--EXPECTF--
+Warning: fopen() expects at least 2 parameters, 0 given in %sfopen.php on line %d
+hihi
+Warning: fopen(notfound.txt): failed to open stream: No such file or directory in phar://%sfopen.phar.php/index.php on line %d
+===DONE===
\ No newline at end of file