mirror of
https://github.com/php/php-src.git
synced 2024-09-22 02:17:32 +00:00
add test for stat interception, fix stat interception
This commit is contained in:
parent
1972f83385
commit
c22b6a76ed
@ -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)) {
|
||||
efree(entry);
|
||||
goto stat_entry;
|
||||
} else {
|
||||
char *save = PHAR_G(cwd), *save2 = entry;
|
||||
int save_len = PHAR_G(cwd_len), save2_len = entry_len;
|
||||
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(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 */
|
||||
#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;
|
||||
#else
|
||||
sb.st_mtime = phar->max_timestamp;
|
||||
sb.st_atime = phar->max_timestamp;
|
||||
sb.st_ctime = phar->max_timestamp;
|
||||
#endif
|
||||
goto statme_baby;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SUCCESS != zend_hash_move_forward(&phar->manifest)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 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);
|
||||
/* 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);
|
||||
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 (!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;
|
||||
#else
|
||||
sb.st_mtime = phar->max_timestamp;
|
||||
sb.st_atime = phar->max_timestamp;
|
||||
sb.st_ctime = phar->max_timestamp;
|
||||
#endif
|
||||
goto statme_baby;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SUCCESS != zend_hash_move_forward(&phar->manifest)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
213
ext/phar/tests/stat.phpt
Normal file
213
ext/phar/tests/stat.phpt
Normal file
@ -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===
|
Loading…
Reference in New Issue
Block a user