]> granicus.if.org Git - php/commitdiff
add test for stat interception, fix stat interception
authorGreg Beaver <cellog@php.net>
Sun, 13 Apr 2008 23:33:31 +0000 (23:33 +0000)
committerGreg Beaver <cellog@php.net>
Sun, 13 Apr 2008 23:33:31 +0000 (23:33 +0000)
ext/phar/func_interceptors.c
ext/phar/tests/stat.phpt [new file with mode: 0644]

index 9866f92eb8652b0f39113c6df73df466de2e1d16..2df88a61704f0aae9575411a636e5312e19865d4 100644 (file)
@@ -503,81 +503,79 @@ void phar_file_stat(const char *filename, php_stat_len filename_length, int type
                        entry = (char *)filename;
                        /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
                        entry_len = (int) filename_length;
-                       if (strstr(entry, "://")) {
+                       if (FAILURE == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) {
                                efree(arch);
                                goto skip_phar;
                        }
-                       if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) {
-                               entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
-                               if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) &data)) {
+                       entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
+                       if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) &data)) {
+                               efree(entry);
+                               goto stat_entry;
+                       } else {
+                               char *save = PHAR_G(cwd), *save2 = entry;
+                               int save_len = PHAR_G(cwd_len), save2_len = entry_len;
+
+                               /* this file is not in the current directory, use the original path */
+                               entry = (char *)filename;
+                               PHAR_G(cwd) = "/";
+                               PHAR_G(cwd_len) = 0;
+                               /* clean path without cwd */
+                               entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
+                               if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry + 1, entry_len - 1, (void **) &data)) {
+                                       PHAR_G(cwd) = save;
+                                       PHAR_G(cwd_len) = save_len;
                                        efree(entry);
+                                       efree(save2);
                                        goto stat_entry;
                                } else {
-                                       char *save = PHAR_G(cwd), *save2 = entry;
-                                       int save_len = PHAR_G(cwd_len), save2_len = entry_len;
-
-                                       /* this file is not in the current directory, use the original path */
-                                       entry = (char *)filename;
-                                       PHAR_G(cwd) = "/";
-                                       PHAR_G(cwd_len) = 0;
-                                       /* clean path without cwd */
-                                       entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
-                                       if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) &data)) {
-                                               PHAR_G(cwd) = save;
-                                               PHAR_G(cwd_len) = save_len;
-                                               efree(entry);
-                                               efree(save2);
-                                               goto stat_entry;
-                                       } else {
-                                               phar_archive_data *phar = *pphar;
-                                               char *key;
-                                               uint keylen;
-                                               ulong unused;
-
-                                               /* original not found either, this is possibly a directory relative to cwd */
-                                               zend_hash_internal_pointer_reset(&phar->manifest);
-                                               while (FAILURE != zend_hash_has_more_elements(&phar->manifest)) {
-                                                       if (HASH_KEY_NON_EXISTANT !=
-                                                                       zend_hash_get_current_key_ex(
-                                                                               &phar->manifest, &key, &keylen, &unused, 0, NULL)) {
-                                                               if (0 == memcmp(save2, key, save2_len)) {
-                                                                       PHAR_G(cwd) = save;
-                                                                       PHAR_G(cwd_len) = save_len;
-                                                                       efree(save2);
-                                                                       efree(entry);
-                                                                       /* directory found, all dirs have the same stat */
-                                                                       if (key[save2_len] == '/') {
-                                                                               sb.st_size = 0;
-                                                                               sb.st_mode = 0777;
-                                                                               sb.st_mode |= S_IFDIR; /* regular directory */
+                                       phar_archive_data *phar = *pphar;
+                                       char *key;
+                                       uint keylen;
+                                       ulong unused;
+
+                                       /* original not found either, this is possibly a directory relative to cwd */
+                                       zend_hash_internal_pointer_reset(&phar->manifest);
+                                       while (FAILURE != zend_hash_has_more_elements(&phar->manifest)) {
+                                               if (HASH_KEY_NON_EXISTANT !=
+                                                               zend_hash_get_current_key_ex(
+                                                                       &phar->manifest, &key, &keylen, &unused, 0, NULL)) {
+                                                       if (!memcmp(save2, key, save2_len)) {
+                                                               PHAR_G(cwd) = save;
+                                                               PHAR_G(cwd_len) = save_len;
+                                                               efree(save2);
+                                                               efree(entry);
+                                                               /* directory found, all dirs have the same stat */
+                                                               if (key[save2_len] == '/') {
+                                                                       sb.st_size = 0;
+                                                                       sb.st_mode = 0777;
+                                                                       sb.st_mode |= S_IFDIR; /* regular directory */
 #ifdef NETWARE
-                                                                               sb.st_mtime.tv_sec = phar->max_timestamp;
-                                                                               sb.st_atime.tv_sec = phar->max_timestamp;
-                                                                               sb.st_ctime.tv_sec = phar->max_timestamp;
+                                                                       sb.st_mtime.tv_sec = phar->max_timestamp;
+                                                                       sb.st_atime.tv_sec = phar->max_timestamp;
+                                                                       sb.st_ctime.tv_sec = phar->max_timestamp;
 #else
-                                                                               sb.st_mtime = phar->max_timestamp;
-                                                                               sb.st_atime = phar->max_timestamp;
-                                                                               sb.st_ctime = phar->max_timestamp;
+                                                                       sb.st_mtime = phar->max_timestamp;
+                                                                       sb.st_atime = phar->max_timestamp;
+                                                                       sb.st_ctime = phar->max_timestamp;
 #endif
-                                                                               goto statme_baby;
-                                                                       }
+                                                                       goto statme_baby;
                                                                }
                                                        }
-                                                       if (SUCCESS != zend_hash_move_forward(&phar->manifest)) {
-                                                               break;
-                                                       }
+                                               }
+                                               if (SUCCESS != zend_hash_move_forward(&phar->manifest)) {
+                                                       break;
                                                }
                                        }
-                                       PHAR_G(cwd) = save;
-                                       PHAR_G(cwd_len) = save_len;
-                                       efree(entry);
-                                       efree(save2);
-                                       /* Error Occured */
-                                       if (!IS_EXISTS_CHECK(type)) {
-                                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", filename);
-                                       }
-                                       RETURN_FALSE;
                                }
+                               PHAR_G(cwd) = save;
+                               PHAR_G(cwd_len) = save_len;
+                               efree(entry);
+                               efree(save2);
+                               /* Error Occured */
+                               if (!IS_EXISTS_CHECK(type)) {
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "l" : "", filename);
+                               }
+                               RETURN_FALSE;
                        }
 stat_entry:
                        if (!data->is_dir) {
@@ -742,7 +740,7 @@ PHAR_FUNC(phar_is_file) /* {{{ */
        }
        if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
                char *arch, *entry, *fname;
-               int arch_len, entry_len, fname_len, free_filename = 0;
+               int arch_len, entry_len, fname_len;
                fname = zend_get_executed_filename(TSRMLS_C);
 
                /* we are checking for existence of a file within the relative path.  Chances are good that this is
@@ -759,17 +757,10 @@ PHAR_FUNC(phar_is_file) /* {{{ */
                        entry = filename;
                        /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
                        entry_len = filename_len;
-                       if (strstr(entry, "://")) {
-                               efree(arch);
-                               if (free_filename) {
-                                       efree(filename);
-                               }
-                               goto skip_phar;
-                       }
                        /* retrieving a file within the current directory, so use this if possible */
                        if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) {
-                               entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
-                               if (zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) {
+                               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 current directory, use the original path */
                                        efree(entry);
                                        efree(arch);
@@ -797,7 +788,7 @@ PHAR_FUNC(phar_is_link) /* {{{ */
        }
        if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
                char *arch, *entry, *fname;
-               int arch_len, entry_len, fname_len, free_filename = 0;
+               int arch_len, entry_len, fname_len;
                fname = zend_get_executed_filename(TSRMLS_C);
 
                /* we are checking for existence of a file within the relative path.  Chances are good that this is
@@ -814,19 +805,12 @@ PHAR_FUNC(phar_is_link) /* {{{ */
                        entry = filename;
                        /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
                        entry_len = filename_len;
-                       if (strstr(entry, "://")) {
-                               efree(arch);
-                               if (free_filename) {
-                                       efree(filename);
-                               }
-                               goto skip_phar;
-                       }
                        /* retrieving a file within the current directory, so use this if possible */
                        if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) {
                                phar_entry_info *etemp;
 
-                               entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
-                               if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) &etemp)) {
+                               entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
+                               if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry + 1, entry_len - 1, (void **) &etemp)) {
                                        /* this file is not in the current directory, use the original path */
                                        efree(entry);
                                        efree(arch);
diff --git a/ext/phar/tests/stat.phpt b/ext/phar/tests/stat.phpt
new file mode 100644 (file)
index 0000000..bc187ab
--- /dev/null
@@ -0,0 +1,213 @@
+--TEST--
+Phar: test stat function interceptions
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip");?>
+--INI--
+phar.require_hash=1
+phar.readonly=0
+--FILE--
+<?php
+Phar::interceptFileFuncs();
+var_dump(stat(""));
+
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$a = new Phar($fname);
+$a['index.php'] = '<?php
+echo "stat\n";
+var_dump(stat("dir/file1.txt"));
+echo "lstat\n";
+var_dump(lstat("dir/file1.txt"));
+echo "fileperms\n";
+var_dump(fileperms("dir/file1.txt"));
+echo "fileinode\n";
+var_dump(fileinode("dir/file1.txt"));
+echo "filesize\n";
+var_dump(filesize("dir/file1.txt"));
+echo "fileowner\n";
+var_dump(fileowner("dir/file1.txt"));
+echo "filegroup\n";
+var_dump(filegroup("dir/file1.txt"));
+echo "filemtime\n";
+var_dump(filemtime("dir/file1.txt"));
+echo "fileatime\n";
+var_dump(fileatime("dir/file1.txt"));
+echo "filectime\n";
+var_dump(filectime("dir/file1.txt"));
+echo "filetype\n";
+var_dump(filetype("dir/file1.txt"));
+echo "is_writable\n";
+var_dump(is_writable("dir/file1.txt"));
+echo "is_writeable\n";
+var_dump(is_writeable("dir/file1.txt"));
+echo "is_readable\n";
+var_dump(is_readable("dir/file1.txt"));
+echo "is_executable\n";
+var_dump(is_executable("dir/file1.txt"));
+echo "file_exists\n";
+var_dump(file_exists("dir/file1.txt"));
+echo "is_dir\n";
+var_dump(is_dir("dir/file1.txt"));
+echo "is_file\n";
+var_dump(is_file("dir/file1.txt"));
+echo "is_link\n";
+var_dump(is_link("dir/file1.txt"));
+?>';
+$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--
+bool(false)
+stat
+array(26) {
+  [0]=>
+  int(12)
+  [1]=>
+  int(51855)
+  [2]=>
+  int(33206)
+  [3]=>
+  int(1)
+  [4]=>
+  int(0)
+  [5]=>
+  int(0)
+  [6]=>
+  int(%s)
+  [7]=>
+  int(2)
+  [8]=>
+  int(%d)
+  [9]=>
+  int(%d)
+  [10]=>
+  int(%d)
+  [11]=>
+  int(%s)
+  [12]=>
+  int(%s)
+  ["dev"]=>
+  int(12)
+  ["ino"]=>
+  int(51855)
+  ["mode"]=>
+  int(33206)
+  ["nlink"]=>
+  int(1)
+  ["uid"]=>
+  int(0)
+  ["gid"]=>
+  int(0)
+  ["rdev"]=>
+  int(%s)
+  ["size"]=>
+  int(2)
+  ["atime"]=>
+  int(%d)
+  ["mtime"]=>
+  int(%d)
+  ["ctime"]=>
+  int(%d)
+  ["blksize"]=>
+  int(%s)
+  ["blocks"]=>
+  int(%s)
+}
+lstat
+array(26) {
+  [0]=>
+  int(12)
+  [1]=>
+  int(51855)
+  [2]=>
+  int(33206)
+  [3]=>
+  int(1)
+  [4]=>
+  int(0)
+  [5]=>
+  int(0)
+  [6]=>
+  int(%s)
+  [7]=>
+  int(2)
+  [8]=>
+  int(%d)
+  [9]=>
+  int(%d)
+  [10]=>
+  int(%d)
+  [11]=>
+  int(%s)
+  [12]=>
+  int(%s)
+  ["dev"]=>
+  int(12)
+  ["ino"]=>
+  int(51855)
+  ["mode"]=>
+  int(33206)
+  ["nlink"]=>
+  int(1)
+  ["uid"]=>
+  int(0)
+  ["gid"]=>
+  int(0)
+  ["rdev"]=>
+  int(%s)
+  ["size"]=>
+  int(2)
+  ["atime"]=>
+  int(%d)
+  ["mtime"]=>
+  int(%d)
+  ["ctime"]=>
+  int(%d)
+  ["blksize"]=>
+  int(%s)
+  ["blocks"]=>
+  int(%s)
+}
+fileperms
+int(33206)
+fileinode
+int(51855)
+filesize
+int(2)
+fileowner
+int(0)
+filegroup
+int(0)
+filemtime
+int(%d)
+fileatime
+int(%d)
+filectime
+int(%d)
+filetype
+string(4) "file"
+is_writable
+bool(true)
+is_writeable
+bool(false)
+is_readable
+bool(true)
+is_executable
+bool(false)
+file_exists
+bool(true)
+is_dir
+bool(false)
+is_file
+bool(true)
+is_link
+bool(false)
+===DONE===
\ No newline at end of file