summaryrefslogtreecommitdiff
path: root/ext/standard/filestat.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/filestat.c')
-rw-r--r--ext/standard/filestat.c108
1 files changed, 79 insertions, 29 deletions
diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c
index 303e919c19..0b488df4b2 100644
--- a/ext/standard/filestat.c
+++ b/ext/standard/filestat.c
@@ -88,11 +88,11 @@ PHP_RINIT_FUNCTION(filestat) /* {{{ */
PHP_RSHUTDOWN_FUNCTION(filestat) /* {{{ */
{
if (BG(CurrentStatFile)) {
- efree (BG(CurrentStatFile));
+ zend_string_release(BG(CurrentStatFile));
BG(CurrentStatFile) = NULL;
}
if (BG(CurrentLStatFile)) {
- efree (BG(CurrentLStatFile));
+ zend_string_release(BG(CurrentLStatFile));
BG(CurrentLStatFile) = NULL;
}
return SUCCESS;
@@ -594,7 +594,7 @@ PHP_FUNCTION(touch)
char *filename;
size_t filename_len;
zend_long filetime = 0, fileatime = 0;
- zend_bool filetime_is_null = 1, fileatime_is_null = 1;
+ bool filetime_is_null = 1, fileatime_is_null = 1;
int ret;
FILE *file;
struct utimbuf newtimebuf;
@@ -674,17 +674,17 @@ PHP_FUNCTION(touch)
#endif
/* {{{ php_clear_stat_cache() */
-PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, size_t filename_len)
+PHPAPI void php_clear_stat_cache(bool clear_realpath_cache, const char *filename, size_t filename_len)
{
/* always clear CurrentStatFile and CurrentLStatFile even if filename is not NULL
* as it may contain outdated data (e.g. "nlink" for a directory when deleting a file
* in this directory, as shown by lstat_stat_variation9.phpt) */
if (BG(CurrentStatFile)) {
- efree(BG(CurrentStatFile));
+ zend_string_release(BG(CurrentStatFile));
BG(CurrentStatFile) = NULL;
}
if (BG(CurrentLStatFile)) {
- efree(BG(CurrentLStatFile));
+ zend_string_release(BG(CurrentLStatFile));
BG(CurrentLStatFile) = NULL;
}
if (clear_realpath_cache) {
@@ -700,7 +700,7 @@ PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *fil
/* {{{ Clear file stat cache */
PHP_FUNCTION(clearstatcache)
{
- zend_bool clear_realpath_cache = 0;
+ bool clear_realpath_cache = 0;
char *filename = NULL;
size_t filename_len = 0;
@@ -720,26 +720,27 @@ PHP_FUNCTION(clearstatcache)
#define IS_ACCESS_CHECK(__t) (IS_ABLE_CHECK(type) || (__t) == FS_EXISTS)
/* {{{ php_stat */
-PHPAPI void php_stat(const char *filename, size_t filename_length, int type, zval *return_value)
+PHPAPI void php_stat(zend_string *filename, int type, zval *return_value)
{
zend_stat_t *stat_sb;
php_stream_statbuf ssb;
int flags = 0, rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */
- const char *local;
- php_stream_wrapper *wrapper;
+ const char *local = NULL;
+ php_stream_wrapper *wrapper = NULL;
- if (!filename_length || CHECK_NULL_PATH(filename, filename_length)) {
- if (filename_length && !IS_EXISTS_CHECK(type)) {
- php_error_docref(NULL, E_WARNING, "Filename contains null byte");
+ if (IS_ACCESS_CHECK(type)) {
+ if (!ZSTR_LEN(filename) || CHECK_NULL_PATH(ZSTR_VAL(filename), ZSTR_LEN(filename))) {
+ if (ZSTR_LEN(filename) && !IS_EXISTS_CHECK(type)) {
+ php_error_docref(NULL, E_WARNING, "Filename contains null byte");
+ }
+ RETURN_FALSE;
}
- RETURN_FALSE;
- }
- if ((wrapper = php_stream_locate_url_wrapper(filename, &local, 0)) == &php_plain_files_wrapper && php_check_open_basedir(local)) {
- RETURN_FALSE;
- }
+ if ((wrapper = php_stream_locate_url_wrapper(ZSTR_VAL(filename), &local, 0)) == &php_plain_files_wrapper
+ && php_check_open_basedir(local)) {
+ RETURN_FALSE;
+ }
- if (IS_ACCESS_CHECK(type)) {
if (wrapper == &php_plain_files_wrapper) {
switch (type) {
@@ -774,13 +775,63 @@ PHPAPI void php_stat(const char *filename, size_t filename_length, int type, zva
flags |= PHP_STREAM_URL_STAT_QUIET;
}
- if (php_stream_stat_path_ex((char *)filename, flags, &ssb, NULL)) {
- /* Error Occurred */
- if (!IS_EXISTS_CHECK(type)) {
- php_error_docref(NULL, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", filename);
+ do {
+ /* Try to hit the cache first */
+ if (flags & PHP_STREAM_URL_STAT_LINK) {
+ if (filename == BG(CurrentLStatFile)
+ || (BG(CurrentLStatFile)
+ && zend_string_equal_content(filename, BG(CurrentLStatFile)))) {
+ memcpy(&ssb, &BG(lssb), sizeof(php_stream_statbuf));
+ break;
+ }
+ } else {
+ if (filename == BG(CurrentStatFile)
+ || (BG(CurrentStatFile)
+ && zend_string_equal_content(filename, BG(CurrentStatFile)))) {
+ memcpy(&ssb, &BG(ssb), sizeof(php_stream_statbuf));
+ break;
+ }
}
- RETURN_FALSE;
- }
+
+ if (!wrapper) {
+ if (!ZSTR_LEN(filename) || CHECK_NULL_PATH(ZSTR_VAL(filename), ZSTR_LEN(filename))) {
+ if (ZSTR_LEN(filename) && !IS_EXISTS_CHECK(type)) {
+ php_error_docref(NULL, E_WARNING, "Filename contains null byte");
+ }
+ RETURN_FALSE;
+ }
+
+ if ((wrapper = php_stream_locate_url_wrapper(ZSTR_VAL(filename), &local, 0)) == &php_plain_files_wrapper
+ && php_check_open_basedir(local)) {
+ RETURN_FALSE;
+ }
+ }
+
+ if (!wrapper
+ || !wrapper->wops->url_stat
+ || wrapper->wops->url_stat(wrapper, local, flags | PHP_STREAM_URL_STAT_IGNORE_OPEN_BASEDIR, &ssb, NULL)) {
+ /* Error Occurred */
+ if (!IS_EXISTS_CHECK(type)) {
+ php_error_docref(NULL, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", ZSTR_VAL(filename));
+ }
+ RETURN_FALSE;
+ }
+
+ /* Drop into cache */
+ if (flags & PHP_STREAM_URL_STAT_LINK) {
+ if (BG(CurrentLStatFile)) {
+ zend_string_release(BG(CurrentLStatFile));
+ }
+ BG(CurrentLStatFile) = zend_string_copy(filename);
+ memcpy(&BG(lssb), &ssb, sizeof(php_stream_statbuf));
+ } else {
+ if (BG(CurrentStatFile)) {
+ zend_string_release(BG(CurrentStatFile));
+ }
+ BG(CurrentStatFile) = zend_string_copy(filename);
+ memcpy(&BG(ssb), &ssb, sizeof(php_stream_statbuf));
+ }
+ } while (0);
stat_sb = &ssb.sb;
@@ -936,14 +987,13 @@ PHPAPI void php_stat(const char *filename, size_t filename_length, int type, zva
/* {{{ FileFunction(name, funcnum) */
#define FileFunction(name, funcnum) \
ZEND_NAMED_FUNCTION(name) { \
- char *filename; \
- size_t filename_len; \
+ zend_string *filename; \
\
ZEND_PARSE_PARAMETERS_START(1, 1) \
- Z_PARAM_STRING(filename, filename_len) \
+ Z_PARAM_STR(filename) \
ZEND_PARSE_PARAMETERS_END(); \
\
- php_stat(filename, filename_len, funcnum, return_value); \
+ php_stat(filename, funcnum, return_value); \
}
/* }}} */