From: Dmitry Stogov Date: Mon, 22 Jan 2007 09:31:46 +0000 (+0000) Subject: Fixed bug #39367 (clearstatcache() doesn't clear realpath cache) X-Git-Tag: RELEASE_1_2_3~19 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=933c26de41ffe84ece5b92a4106208497c9ea331;p=php Fixed bug #39367 (clearstatcache() doesn't clear realpath cache) Fixed bug #40092 (chroot() doesn't clear realpath cache) --- diff --git a/NEWS b/NEWS index 57c33e9779..8295fb0aa0 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,10 @@ PHP NEWS (Tony) - Fixed bug #40169 (CURLOPT_TCP_NODELAY only available in curl >= 7.11.2). (Tony) +- Fixed bug #40092 (chroot() doesn't clear realpath cache). (Dmitry) - Fixed bug #39450 (getenv() fills other super-globals). (Ilia, Tony) +- Fixed bug #39367 (clearstatcache() doesn't clear realpath cache). + (j at pureftpd dot org, Dmitry) 18 Jan 2007, PHP 5.2.1RC3 - Added read-timeout context option "timeout" for HTTP streams. (Hannes, diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c index 959cc7d76e..36bce0b5e9 100644 --- a/TSRM/tsrm_virtual_cwd.c +++ b/TSRM/tsrm_virtual_cwd.c @@ -249,18 +249,7 @@ static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC) static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals TSRMLS_DC) { CWD_STATE_FREE(&cwd_globals->cwd); - { - int i; - - for (i = 0; i < sizeof(cwd_globals->realpath_cache)/sizeof(cwd_globals->realpath_cache[0]); i++) { - realpath_cache_bucket *p = cwd_globals->realpath_cache[i]; - while (p != NULL) { - realpath_cache_bucket *r = p; - p = p->next; - free(r); - } - } - } + realpath_cache_clean(TSRMLS_C); } static char *tsrm_strndup(const char *s, size_t length) @@ -394,6 +383,42 @@ static inline unsigned long realpath_cache_key(const char *path, int path_len) return h; } +CWD_API void realpath_cache_clean(TSRMLS_D) +{ + int i; + + for (i = 0; i < sizeof(CWDG(realpath_cache))/sizeof(CWDG(realpath_cache)[0]); i++) { + realpath_cache_bucket *p = CWDG(realpath_cache)[i]; + while (p != NULL) { + realpath_cache_bucket *r = p; + p = p->next; + free(r); + } + CWDG(realpath_cache)[i] = NULL; + } + CWDG(realpath_cache_size) = 0; +} + +CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC) +{ + unsigned long key = realpath_cache_key(path, path_len); + unsigned long n = key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0])); + realpath_cache_bucket **bucket = &CWDG(realpath_cache)[n]; + + while (*bucket != NULL) { + if (key == (*bucket)->key && path_len == (*bucket)->path_len && + memcmp(path, (*bucket)->path, path_len) == 0) { + realpath_cache_bucket *r = *bucket; + *bucket = (*bucket)->next; + CWDG(realpath_cache_size) -= sizeof(realpath_cache_bucket) + r->path_len + 1 + r->realpath_len + 1; + free(r); + return; + } else { + bucket = &(*bucket)->next; + } + } +} + static inline void realpath_cache_add(const char *path, int path_len, const char *realpath, int realpath_len, time_t t TSRMLS_DC) { long size = sizeof(realpath_cache_bucket) + path_len + 1 + realpath_len + 1; diff --git a/TSRM/tsrm_virtual_cwd.h b/TSRM/tsrm_virtual_cwd.h index b029823fd9..437cc45348 100644 --- a/TSRM/tsrm_virtual_cwd.h +++ b/TSRM/tsrm_virtual_cwd.h @@ -226,6 +226,9 @@ extern virtual_cwd_globals cwd_globals; # define CWDG(v) (cwd_globals.v) #endif +CWD_API void realpath_cache_clean(TSRMLS_D); +CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC); + /* The actual macros to be used in programs using TSRM * If the program defines VIRTUAL_DIR it will use the * virtual_* functions diff --git a/ext/standard/dir.c b/ext/standard/dir.c index 376c0e4590..fd8b4140cb 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -257,12 +257,13 @@ PHP_FUNCTION(chroot) } ret = chroot(str); - if (ret != 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno); RETURN_FALSE; } + realpath_cache_clean(TSRMLS_C); + ret = chdir("/"); if (ret != 0) { diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index b68dec9366..4411924d49 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -673,6 +673,7 @@ PHP_FUNCTION(clearstatcache) efree(BG(CurrentLStatFile)); BG(CurrentLStatFile) = NULL; } + realpath_cache_clean(TSRMLS_C); } /* }}} */ diff --git a/ext/standard/tests/file/bug39367.phpt b/ext/standard/tests/file/bug39367.phpt new file mode 100755 index 0000000000..667e33dca1 --- /dev/null +++ b/ext/standard/tests/file/bug39367.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #39367 (clearstatcache() doesn't clear realpath cache) +--FILE-- + +--EXPECT-- +ok