From: Greg Beaver Date: Sun, 13 Apr 2008 23:33:31 +0000 (+0000) Subject: add test for stat interception, fix stat interception X-Git-Tag: RELEASE_2_0_0b1~435 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c22b6a76ed892cd8921e4962dfab8db2207bf81d;p=php add test for stat interception, fix stat interception --- diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index 9866f92eb8..2df88a6170 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -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:/// */ 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:/// */ 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:/// */ 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 index 0000000000..bc187ab8aa --- /dev/null +++ b/ext/phar/tests/stat.phpt @@ -0,0 +1,213 @@ +--TEST-- +Phar: test stat function interceptions +--SKIPIF-- + +--INI-- +phar.require_hash=1 +phar.readonly=0 +--FILE-- +'; +$a['dir/file1.txt'] = 'hi'; +$a['dir/file2.txt'] = 'hi2'; +$a['dir/file3.txt'] = 'hi3'; +$a->setStub(' +===DONE=== +--CLEAN-- + +--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