]> granicus.if.org Git - php/commitdiff
MFH: fix #39351 (relative include fails on Solaris)
authorAntony Dovgal <tony2001@php.net>
Tue, 3 Apr 2007 20:20:56 +0000 (20:20 +0000)
committerAntony Dovgal <tony2001@php.net>
Tue, 3 Apr 2007 20:20:56 +0000 (20:20 +0000)
TSRM/tsrm_virtual_cwd.c

index fd253309eeea4042e45dfc59e0eb0469fd643273..b00d83187ffd09ca9c1326c65a4f14bc30c90b0a 100644 (file)
@@ -474,7 +474,11 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
        realpath_cache_bucket *bucket;
        time_t t = 0;
        int ret;
+       int use_cache;
+       int use_relative_path = 0;
        TSRMLS_FETCH();
+       
+       use_cache = ((use_realpath != CWD_EXPAND) && CWDG(realpath_cache_size_limit));
 
        if (path_length == 0) 
                return (0);
@@ -488,27 +492,32 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
        /* 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 > 0)) {
-               int orig_path_len;
-               int state_cwd_length = state->cwd_length;
+       if (!IS_ABSOLUTE_PATH(path, path_length)) {
+               if (state->cwd_length == 0) {
+                       use_cache = 0;
+                       use_relative_path = 1;
+               } else {
+                       int orig_path_len;
+                       int state_cwd_length = state->cwd_length;
 
 #ifdef TSRM_WIN32
-               if (IS_SLASH(path[0])) {
-                       state_cwd_length = 2;
-               }
+                       if (IS_SLASH(path[0])) {
+                               state_cwd_length = 2;
+                       }
 #endif
-               orig_path_len = path_length + state_cwd_length + 1;
-               if (orig_path_len >= MAXPATHLEN) {
-                       return 1;
+                       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; 
                }
-               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 != CWD_EXPAND && CWDG(realpath_cache_size_limit)) {
+       if (use_cache) {
                t = CWDG(realpath_cache_ttl)?time(NULL):0;
                if ((bucket = realpath_cache_find(path, path_length, t TSRMLS_CC)) != NULL) {           
                        int len = bucket->realpath_len;
@@ -591,6 +600,12 @@ no_realpath:
                        if (IS_DIRECTORY_UP(ptr, ptr_length)) {
                                char save;
 
+                               if (use_relative_path) {
+                                       CWD_STATE_FREE(state);
+                                       *state = old_state;
+                                       return 1;
+                               }
+
                                save = DEFAULT_SLASH;
 
 #define PREVIOUS state->cwd[state->cwd_length - 1]
@@ -610,33 +625,38 @@ no_realpath:
                                        state->cwd_length--;
                                }
                        } else if (!IS_DIRECTORY_CURRENT(ptr, ptr_length)) {
-                               state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1+1);
+                               if (use_relative_path) {
+                                       state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1);
+                                       use_relative_path = 0;
+                               } else {
+                                       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_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;
-                               }
+                                       /* Windows 9x will consider C:\\Foo as a network path. Avoid it. */
+                                       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;
+                                       }
 #elif defined(NETWARE)
-                               /* 
-                               Below code keeps appending to state->cwd a File system seperator
-                               cases where this appending should not happen is given below,
-                               a) sys: should just be left as it is
-                               b) sys:system should just be left as it is,
-                                       Colon is allowed only in the first token as volume names alone can have the : in their names.
-                                       Files and Directories cannot have : in their names
-                                       So the check goes like this,
-                                       For second token and above simply append the DEFAULT_SLASH to the state->cwd.
-                                       For first token check for the existence of : 
-                                       if it exists don't append the DEFAULT_SLASH to the state->cwd.
-                               */
-                               if(((state->cwd_length == 0) && (strchr(ptr, ':') == NULL)) || (state->cwd_length > 0)) {
-                                       state->cwd[state->cwd_length++] = DEFAULT_SLASH;
-                               }
+                                       /* 
+                                       Below code keeps appending to state->cwd a File system seperator
+                                       cases where this appending should not happen is given below,
+                                       a) sys: should just be left as it is
+                                       b) sys:system should just be left as it is,
+                                               Colon is allowed only in the first token as volume names alone can have the : in their names.
+                                               Files and Directories cannot have : in their names
+                                               So the check goes like this,
+                                               For second token and above simply append the DEFAULT_SLASH to the state->cwd.
+                                               For first token check for the existence of : 
+                                               if it exists don't append the DEFAULT_SLASH to the state->cwd.
+                                       */
+                                       if(((state->cwd_length == 0) && (strchr(ptr, ':') == NULL)) || (state->cwd_length > 0)) {
+                                               state->cwd[state->cwd_length++] = DEFAULT_SLASH;
+                                       }
 #else
-                               state->cwd[state->cwd_length++] = DEFAULT_SLASH;
+                                       state->cwd[state->cwd_length++] = DEFAULT_SLASH;
 #endif
+                               }
                                memcpy(&state->cwd[state->cwd_length], ptr, ptr_length+1);
 
 #ifdef TSRM_WIN32
@@ -687,7 +707,7 @@ no_realpath:
                }
        }
 
-       if (use_realpath != CWD_EXPAND && CWDG(realpath_cache_size_limit)) {
+       if (use_cache) {
                realpath_cache_add(path, path_length, state->cwd, state->cwd_length, t TSRMLS_CC);
        }