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

Reply via email to