dmitry Wed Sep 20 07:35:59 2006 UTC
Added files: (Branch: PHP_5_2)
/php-src/tests/lang bug38579.inc bug38579.phpt
Modified files:
/php-src NEWS
/TSRM tsrm_virtual_cwd.c
Log:
Fixed bug #38579 (include_once() may include the same file twice)
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.259&r2=1.2027.2.547.2.260&diff_format=u
Index: php-src/NEWS
diff -u php-src/NEWS:1.2027.2.547.2.259 php-src/NEWS:1.2027.2.547.2.260
--- php-src/NEWS:1.2027.2.547.2.259 Tue Sep 19 21:36:53 2006
+++ php-src/NEWS Wed Sep 20 07:35:58 2006
@@ -8,6 +8,7 @@
(Tony)
- Fixed bug #38623 (leaks in a tricky code with switch() and exceptions).
(Dmitry)
+- Fixed bug #38579 (include_once() may include the same file twice). (Dmitry)
- Fixed bug #38574 (missing curl constants and improper constant detection).
(Ilia)
- Fixed bug #37870 (pgo_pgsql tries to de-allocate unused statements).
http://cvs.php.net/viewvc.cgi/TSRM/tsrm_virtual_cwd.c?r1=1.74.2.9.2.3&r2=1.74.2.9.2.4&diff_format=u
Index: TSRM/tsrm_virtual_cwd.c
diff -u TSRM/tsrm_virtual_cwd.c:1.74.2.9.2.3
TSRM/tsrm_virtual_cwd.c:1.74.2.9.2.4
--- TSRM/tsrm_virtual_cwd.c:1.74.2.9.2.3 Sat Aug 5 13:17:50 2006
+++ TSRM/tsrm_virtual_cwd.c Wed Sep 20 07:35:58 2006
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: tsrm_virtual_cwd.c,v 1.74.2.9.2.3 2006/08/05 13:17:50 tony2001 Exp $ */
+/* $Id: tsrm_virtual_cwd.c,v 1.74.2.9.2.4 2006/09/20 07:35:58 dmitry Exp $ */
#include <sys/types.h>
#include <sys/stat.h>
@@ -366,23 +366,11 @@
CWD_API int virtual_file_ex(cwd_state *state, const char *path,
verify_path_func verify_path, int use_realpath)
{
int path_length = strlen(path);
- char *ptr, *path_copy;
- char *tok = NULL;
- int ptr_length;
cwd_state old_state;
- int ret = 0;
- int copy_amount = -1;
- char *free_path;
- unsigned char is_absolute = 0;
-#ifndef TSRM_WIN32
- char resolved_path[MAXPATHLEN];
-#else
- char *new_path;
-#endif
char orig_path[MAXPATHLEN];
- int orig_path_len = 0;
realpath_cache_bucket *bucket;
time_t t = 0;
+ int ret;
TSRMLS_FETCH();
if (path_length == 0)
@@ -390,21 +378,29 @@
if (path_length >= MAXPATHLEN)
return (1);
- if (use_realpath && CWDG(realpath_cache_size_limit)) {
- if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length <
1)) {
- memcpy(orig_path, path, path_length+1);
- orig_path_len = path_length;
- } else {
- orig_path_len = path_length + state->cwd_length + 1;
- if (orig_path_len >= MAXPATHLEN) {
- return 1;
- }
- memcpy(orig_path, state->cwd, state->cwd_length);
- orig_path[state->cwd_length] = DEFAULT_SLASH;
- memcpy(orig_path + state->cwd_length + 1, path,
path_length + 1);
+#if VIRTUAL_CWD_DEBUG
+ fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path);
+#endif
+
+ /* cwd_length can be 0 when getcwd() fails.
+ * This can happen under solaris when a dir does not have read
permissions
+ * but *does* have execute permissions */
+ if (!IS_ABSOLUTE_PATH(path, path_length) && (state->cwd_length > 1)) {
+ int orig_path_len = path_length + state->cwd_length + 1;
+
+ if (orig_path_len >= MAXPATHLEN) {
+ return 1;
}
+ memcpy(orig_path, state->cwd, state->cwd_length);
+ orig_path[state->cwd_length] = DEFAULT_SLASH;
+ memcpy(orig_path + state->cwd_length + 1, path, path_length +
1);
+ path = orig_path;
+ path_length = orig_path_len;
+ }
+
+ if (use_realpath && CWDG(realpath_cache_size_limit)) {
t = CWDG(realpath_cache_ttl)?time(NULL):0;
- if ((bucket = realpath_cache_find(orig_path, orig_path_len, t
TSRMLS_CC)) != NULL) {
+ if ((bucket = realpath_cache_find(path, path_length, t
TSRMLS_CC)) != NULL) {
int len = bucket->realpath_len;
CWD_STATE_COPY(&old_state, state);
@@ -421,107 +417,55 @@
}
}
}
+
+ if (use_realpath) {
#if !defined(TSRM_WIN32) && !defined(NETWARE)
- /* cwd_length can be 0 when getcwd() fails.
- * This can happen under solaris when a dir does not have read
permissions
- * but *does* have execute permissions */
- if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) {
- if (use_realpath) {
- if (realpath(path, resolved_path)) { /* Note: Not
threadsafe on older *BSD's */
- path = resolved_path;
- path_length = strlen(path);
- } else {
- /* disable for now
- return 1; */
- }
- }
- } else { /* Concat current directory with relative path and then run
realpath() on it */
- char *tmp;
- char *ptr;
+ char resolved_path[MAXPATHLEN];
- ptr = tmp = (char *)
malloc(state->cwd_length+path_length+sizeof("/"));
- if (!tmp) {
- return 1;
- }
- memcpy(ptr, state->cwd, state->cwd_length);
- ptr += state->cwd_length;
- *ptr++ = DEFAULT_SLASH;
- memcpy(ptr, path, path_length);
- ptr += path_length;
- *ptr = '\0';
- if (strlen(tmp) >= MAXPATHLEN) {
- free(tmp);
- return 1;
- }
- if (use_realpath) {
- if (realpath(tmp, resolved_path)) {
- path = resolved_path;
- path_length = strlen(path);
- } else {
- /* disable for now
- free(tmp);
- return 1; */
- }
- }
- free(tmp);
- }
-#endif
-#if defined(TSRM_WIN32)
- {
- int new_path_length;
-
- new_path_length = GetLongPathName(path, NULL, 0);
- if (new_path_length == 0) {
- goto php_failed_getlongpath;
+ if (!realpath(path, resolved_path)) { /* Note: Not threadsafe
on older *BSD's */
+ goto no_realpath;
}
+ CWD_STATE_COPY(&old_state, state);
- /* GetLongPathName already counts the \0 */
- new_path = (char *) malloc(new_path_length);
- if (!new_path) {
- return 1;
- }
-
- if (GetLongPathName(path, new_path, new_path_length) != 0) {
- path = new_path;
- path_length = new_path_length;
- } else {
- free(new_path);
-php_failed_getlongpath:
- new_path = NULL;
- }
- }
+ state->cwd_length = strlen(resolved_path);
+ state->cwd = (char *) realloc(state->cwd, state->cwd_length+1);
+ memcpy(state->cwd, resolved_path, state->cwd_length+1);
+#else
+ goto no_realpath;
#endif
- free_path = path_copy = tsrm_strndup(path, path_length);
-
- CWD_STATE_COPY(&old_state, state);
-#if VIRTUAL_CWD_DEBUG
- fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path);
+ } else {
+ char *ptr, *path_copy, *free_path;
+ char *tok = NULL;
+ int ptr_length;
+
+no_realpath:
+
+ free_path = path_copy = tsrm_strndup(path, path_length);
+ CWD_STATE_COPY(&old_state, state);
+
+#ifdef TSRM_WIN32
+ if (path_length >= 2 && path[1] == ':') {
+ state->cwd = (char *) realloc(state->cwd, 2 + 1);
+ state->cwd[0] = toupper(path[0]);
+ state->cwd[1] = ':';
+ state->cwd[2] = '\0';
+ state->cwd_length = 2;
+ path_copy += 2;
+ } else if (IS_UNC_PATH(path, path_length)) {
+ state->cwd = (char *) realloc(state->cwd, 1 + 1);
+ state->cwd[0] = DEFAULT_SLASH;
+ state->cwd[1] = '\0';
+ state->cwd_length = 1;
+ path_copy += 2;
+ } else {
#endif
- if (IS_ABSOLUTE_PATH(path_copy, path_length)) {
- copy_amount = COPY_WHEN_ABSOLUTE(path_copy);
- is_absolute = 1;
+ state->cwd = (char *) realloc(state->cwd, 1);
+ state->cwd[0] = '\0';
+ state->cwd_length = 0;
#ifdef TSRM_WIN32
- } else if (IS_SLASH(path_copy[0])) {
- copy_amount = 2;
-#endif
- }
-
- if (copy_amount != -1) {
- state->cwd = (char *) realloc(state->cwd, copy_amount + 1);
- if (copy_amount) {
- if (is_absolute) {
- memcpy(state->cwd, path_copy, copy_amount);
- path_copy += copy_amount;
- } else {
- memcpy(state->cwd, old_state.cwd, copy_amount);
- }
}
- state->cwd[copy_amount] = '\0';
- state->cwd_length = copy_amount;
- }
-
-
- if (state->cwd_length > 0 || IS_ABSOLUTE_PATH(path, path_length)) {
+#endif
+
ptr = tsrm_strtok_r(path_copy, TOKENIZER_STRING, &tok);
while (ptr) {
ptr_length = strlen(ptr);
@@ -551,7 +495,8 @@
state->cwd = (char *) realloc(state->cwd,
state->cwd_length+ptr_length+1+1);
#ifdef TSRM_WIN32
/* Windows 9x will consider C:\\Foo as a
network path. Avoid it. */
- if ((state->cwd[state->cwd_length-1]!='\\' &&
state->cwd[state->cwd_length-1]!='/') ||
+ if (state->cwd_length < 2 ||
+ (state->cwd[state->cwd_length-1]!='\\' &&
state->cwd[state->cwd_length-1]!='/') ||
IsDBCSLeadByte(state->cwd[state->cwd_length-2])) {
state->cwd[state->cwd_length++] =
DEFAULT_SLASH;
}
@@ -575,32 +520,42 @@
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
#endif
memcpy(&state->cwd[state->cwd_length], ptr,
ptr_length+1);
+
+#ifdef TSRM_WIN32
+ if (use_realpath) {
+ WIN32_FIND_DATA data;
+ HANDLE hFind;
+
+ if ((hFind = FindFirstFile(state->cwd,
&data)) != INVALID_HANDLE_VALUE) {
+ int length =
strlen(data.cFileName);
+
+ if (length != ptr_length) {
+ state->cwd = (char *)
realloc(state->cwd, state->cwd_length+length+1);
+ }
+
memcpy(&state->cwd[state->cwd_length], data.cFileName, length+1);
+ ptr_length = length;
+ FindClose(hFind);
+ }
+ }
+#endif
+
state->cwd_length += ptr_length;
}
ptr = tsrm_strtok_r(NULL, TOKENIZER_STRING, &tok);
}
+ free(free_path);
+
if (state->cwd_length == COPY_WHEN_ABSOLUTE(state->cwd)) {
state->cwd = (char *) realloc(state->cwd,
state->cwd_length+1+1);
state->cwd[state->cwd_length] = DEFAULT_SLASH;
state->cwd[state->cwd_length+1] = '\0';
state->cwd_length++;
}
- } else {
- state->cwd = (char *) realloc(state->cwd, path_length+1);
- memcpy(state->cwd, path, path_length+1);
- state->cwd_length = path_length;
}
-#ifdef TSRM_WIN32
- if (new_path) {
- free(new_path);
- }
-#endif
- free(free_path);
-
if (use_realpath && CWDG(realpath_cache_size_limit)) {
- realpath_cache_add(orig_path, orig_path_len, state->cwd,
state->cwd_length, t TSRMLS_CC);
+ realpath_cache_add(path, path_length, state->cwd,
state->cwd_length, t TSRMLS_CC);
}
if (verify_path && verify_path(state)) {
http://cvs.php.net/viewvc.cgi/php-src/tests/lang/bug38579.inc?view=markup&rev=1.1
Index: php-src/tests/lang/bug38579.inc
+++ php-src/tests/lang/bug38579.inc
http://cvs.php.net/viewvc.cgi/php-src/tests/lang/bug38579.phpt?view=markup&rev=1.1
Index: php-src/tests/lang/bug38579.phpt
+++ php-src/tests/lang/bug38579.phpt
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php