]> granicus.if.org Git - php/commitdiff
Fix for Bug #21310, based on a patch by jflemer@php.net.
authorWez Furlong <wez@php.net>
Mon, 17 Mar 2003 13:40:45 +0000 (13:40 +0000)
committerWez Furlong <wez@php.net>
Mon, 17 Mar 2003 13:40:45 +0000 (13:40 +0000)
TSRM/tsrm_virtual_cwd.c
acinclude.m4
configure.in
main/main.c
main/safe_mode.c

index 082cdf96a5e841651088df26525114dfaf40e500..d62745ad326c4bfccc0b9a13f41a3e8c407bb66a 100644 (file)
@@ -303,7 +303,10 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
                return (0);
 
 #if !defined(TSRM_WIN32) && !defined(NETWARE)
-       if (IS_ABSOLUTE_PATH(path, path_length)) {
+       /* 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 && realpath(path, resolved_path)) {
                        path = resolved_path;
                        path_length = strlen(path);
@@ -360,58 +363,64 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
        }
 
 
-       ptr = tsrm_strtok_r(path_copy, TOKENIZER_STRING, &tok);
-       while (ptr) {
-               ptr_length = strlen(ptr);
+       if (state->cwd_length > 0 || IS_ABSOLUTE_PATH(path, path_length)) {
+               ptr = tsrm_strtok_r(path_copy, TOKENIZER_STRING, &tok);
+               while (ptr) {
+                       ptr_length = strlen(ptr);
 
-               if (IS_DIRECTORY_UP(ptr, ptr_length)) {
-                       char save;
+                       if (IS_DIRECTORY_UP(ptr, ptr_length)) {
+                               char save;
 
-                       save = DEFAULT_SLASH;
+                               save = DEFAULT_SLASH;
 
 #define PREVIOUS state->cwd[state->cwd_length - 1]
 
-                       while (IS_ABSOLUTE_PATH(state->cwd, state->cwd_length) &&
-                                       !IS_SLASH(PREVIOUS)) {
-                               save = PREVIOUS;
-                               PREVIOUS = '\0';
-                               state->cwd_length--;
-                       }
-
-                       if (!IS_ABSOLUTE_PATH(state->cwd, state->cwd_length)) {
-                               state->cwd[state->cwd_length++] = save;
-                               state->cwd[state->cwd_length] = '\0';
-                       } else {
-                               PREVIOUS = '\0';
-                               state->cwd_length--;
-                       }
-               } else if (!IS_DIRECTORY_CURRENT(ptr, ptr_length)) {
-                       state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1+1);
+                               while (IS_ABSOLUTE_PATH(state->cwd, state->cwd_length) &&
+                                               !IS_SLASH(PREVIOUS)) {
+                                       save = PREVIOUS;
+                                       PREVIOUS = '\0';
+                                       state->cwd_length--;
+                               }
+
+                               if (!IS_ABSOLUTE_PATH(state->cwd, state->cwd_length)) {
+                                       state->cwd[state->cwd_length++] = save;
+                                       state->cwd[state->cwd_length] = '\0';
+                               } else {
+                                       PREVIOUS = '\0';
+                                       state->cwd_length--;
+                               }
+                       } else if (!IS_DIRECTORY_CURRENT(ptr, ptr_length)) {
+                               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]!='/') || 
-                               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[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)
-            /* If the token is a volume name, it will have colon at the end -- so, no slash before it */
-            if (ptr[ptr_length-1] != ':') {
-                               state->cwd[state->cwd_length++] = DEFAULT_SLASH;
-                       }
+                               /* If the token is a volume name, it will have colon at the end -- so, no slash before it */
+                               if (ptr[ptr_length-1] != ':') {
+                                       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);
-                       state->cwd_length += ptr_length;
+                               memcpy(&state->cwd[state->cwd_length], ptr, ptr_length+1);
+                               state->cwd_length += ptr_length;
+                       }
+                       ptr = tsrm_strtok_r(NULL, TOKENIZER_STRING, &tok);
                }
-               ptr = tsrm_strtok_r(NULL, TOKENIZER_STRING, &tok);
-       }
 
-       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++;
+               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;
        }
 
        if (verify_path && verify_path(state)) {
index fd616da1ec0b3d1bd361d6a32a7f04ca653d7211..0971796bbfbca483ed56fbd4329e52b770165419 100644 (file)
@@ -1441,6 +1441,20 @@ int main(void) {
   fi
 ])
 
+dnl Some systems, notably Solaris, cause getcwd() or realpath to fail if a
+dnl component of the path has execute but not read permissions
+AC_DEFUN([PHP_BROKEN_GETCWD],[
+  AC_MSG_CHECKING([for broken getcwd])
+  os=`uname -sr 2>/dev/null`
+  case $os in
+    SunOS*)
+         AC_DEFINE(HAVE_BROKEN_GETCWD,1, [Define if system has broken getcwd])
+         AC_MSG_RESULT([yes]);;
+       *)
+         AC_MSG_RESULT([no]);;
+  esac
+])
+
 AC_DEFUN([PHP_BROKEN_GLIBC_FOPEN_APPEND],[
   AC_MSG_CHECKING([for broken libc stdio])
   AC_CACHE_VAL(have_broken_glibc_fopen_append,[
index bd46c8e96b60161d39eaddc5774762208b740cdd..2d0c3671593e73f8e8590dfb9ae445df02324d5d 100644 (file)
@@ -378,6 +378,7 @@ sys/ipc.h \
 ])
 
 PHP_FOPENCOOKIE
+PHP_BROKEN_GETCWD
 PHP_BROKEN_GLIBC_FOPEN_APPEND
 
 dnl Checks for typedefs, structures, and compiler characteristics.
index f98de09e9eb4886b35db8ec5bdd0cb8b38ba7868..99a17b9ebf9c030d24760585c0a92215a26ab8c8 100644 (file)
@@ -1507,7 +1507,11 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
 {
        zend_file_handle *prepend_file_p, *append_file_p;
        zend_file_handle prepend_file, append_file;
+#if HAVE_BROKEN_GETCWD 
+       int old_cwd_fd;
+#else
        char *old_cwd;
+#endif
        char *old_primary_file_path = NULL;
        int retval = 0;
 
@@ -1515,9 +1519,11 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
        if (php_handle_special_queries(TSRMLS_C)) {
                return 0;
        }
-#define OLD_CWD_SIZE 4096
+#ifndef HAVE_BROKEN_GETCWD
+# define OLD_CWD_SIZE 4096
        old_cwd = do_alloca(OLD_CWD_SIZE);
        old_cwd[0] = '\0';
+#endif
 
        zend_try {
 #ifdef PHP_WIN32
@@ -1528,7 +1534,12 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
 
                if (primary_file->type == ZEND_HANDLE_FILENAME 
                                && primary_file->filename) {
+#if HAVE_BROKEN_GETCWD
+                       /* this looks nasty to me */
+                       old_cwd_fd = open(".", 0);
+#else
                        VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1);
+#endif
                        VCWD_CHDIR_FILE(primary_file->filename);
                }
 
@@ -1580,10 +1591,15 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
                
        } zend_end_try();
 
+#if HAVE_BROKEN_GETCWD
+       fchdir(old_cwd_fd);
+       close(old_cwd_fd);
+#else
        if (old_cwd[0] != '\0') {
                VCWD_CHDIR(old_cwd);
        }
        free_alloca(old_cwd);
+#endif
        return retval;
 }
 /* }}} */
index 4c21cb49d754a6c098bd0e350d61808e9708d391..c7e3fd7abe8a2839b16f098b73b27712cdd46c7e 100644 (file)
@@ -126,6 +126,11 @@ PHPAPI int php_checkuid_ex(const char *filename, char *fopen_mode, int mode, int
                        VCWD_REALPATH(filename, path);
                        *s = DEFAULT_SLASH;
                } else {
+                       /* Under Solaris, getcwd() can fail if there are no
+                        * read permissions on a component of the path, even
+                        * though it has the required x permissions */
+                       path[0] = '.';
+                       path[1] = '\0';
                        VCWD_GETCWD(path, sizeof(path));
                }
        } /* end CHECKUID_ALLOW_ONLY_DIR */