dmitry                                   Mon, 30 Nov 2009 14:21:23 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=291496

Log:
Fixed bug #50159 (wrong working directory in symlinked files)

Bug: http://bugs.php.net/50159 (Assigned) wrong working directory in symlinked 
files
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    U   php/php-src/branches/PHP_5_3/main/fopen_wrappers.c
    U   php/php-src/trunk/main/fopen_wrappers.c

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS	2009-11-30 14:10:11 UTC (rev 291495)
+++ php/php-src/branches/PHP_5_3/NEWS	2009-11-30 14:21:23 UTC (rev 291496)
@@ -46,6 +46,7 @@
 - Fixed bug #50185 (ldap_get_entries() return false instead of an empty array
   when there is no error). (Jani)
 - Fixed bug #50174 (Incorrectly matched docComment). (Felipe)
+- Fixed bug #50159 (wrong working directory in symlinked files). (Dmitry)
 - Fixed bug #50158 (FILTER_VALIDATE_EMAIL fails with valid addresses
   containing = or ?). (Pierrick)
 - Fixed bug #50152 (ReflectionClass::hasProperty behaves like isset() not

Modified: php/php-src/branches/PHP_5_3/main/fopen_wrappers.c
===================================================================
--- php/php-src/branches/PHP_5_3/main/fopen_wrappers.c	2009-11-30 14:10:11 UTC (rev 291495)
+++ php/php-src/branches/PHP_5_3/main/fopen_wrappers.c	2009-11-30 14:21:23 UTC (rev 291496)
@@ -386,16 +386,16 @@
 #ifndef PHP_WIN32
 	struct stat st;
 #endif
-	char *path_info, *filename;
+	char *path_info;
+	char *filename = NULL;
+	char *resolved_path = NULL;
 	int length;

-	filename = SG(request_info).path_translated;
 	path_info = SG(request_info).request_uri;
 #if HAVE_PWD_H
 	if (PG(user_dir) && *PG(user_dir) && path_info && '/' == path_info[0] && '~' == path_info[1]) {
 		char *s = strchr(path_info + 2, '/');

-		filename = NULL;	/* discard the original filename, it must not be used */
 		if (s) {			/* if there is no path name after the file, do not bother */
 			char user[32];			/* to try open the directory */
 			struct passwd *pw;
@@ -426,39 +426,41 @@
 #endif
 			if (pw && pw->pw_dir) {
 				spprintf(&filename, 0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */
-				STR_FREE(SG(request_info).path_translated);
-				SG(request_info).path_translated = filename;
-			}
+			} else {
+				filename = SG(request_info).path_translated;
+			}
 #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
 			efree(pwbuf);
 #endif
 		}
 	} else
 #endif
-	if (PG(doc_root) && path_info) {
-		length = strlen(PG(doc_root));
-		if (IS_ABSOLUTE_PATH(PG(doc_root), length)) {
-			filename = emalloc(length + strlen(path_info) + 2);
-			if (filename) {
-				memcpy(filename, PG(doc_root), length);
-				if (!IS_SLASH(filename[length - 1])) {	/* length is never 0 */
-					filename[length++] = PHP_DIR_SEPARATOR;
-				}
-				if (IS_SLASH(path_info[0])) {
-					length--;
-				}
-				strcpy(filename + length, path_info);
-				STR_FREE(SG(request_info).path_translated);
-				SG(request_info).path_translated = filename;
+	if (PG(doc_root) && path_info && (length = strlen(PG(doc_root)) &&
+		IS_ABSOLUTE_PATH(PG(doc_root), length))) {
+		filename = emalloc(length + strlen(path_info) + 2);
+		if (filename) {
+			memcpy(filename, PG(doc_root), length);
+			if (!IS_SLASH(filename[length - 1])) {	/* length is never 0 */
+				filename[length++] = PHP_DIR_SEPARATOR;
 			}
+			if (IS_SLASH(path_info[0])) {
+				length--;
+			}
+			strcpy(filename + length, path_info);
 		}
-	} /* if doc_root && path_info */
+	} else {
+		filename = SG(request_info).path_translated;
+	}

+
 	if (filename) {
-		filename = zend_resolve_path(filename, strlen(filename) TSRMLS_CC);
+		resolved_path = zend_resolve_path(filename, strlen(filename) TSRMLS_CC);
 	}

-	if (!filename) {
+	if (!resolved_path) {
+		if (SG(request_info).path_translated != filename) {
+			STR_FREE(filename);
+		}
 		/* we have to free SG(request_info).path_translated here because
 		 * php_destroy_request_info assumes that it will get
 		 * freed when the include_names hash is emptied, but
@@ -467,7 +469,7 @@
 		SG(request_info).path_translated = NULL;
 		return FAILURE;
 	}
-	fp = VCWD_FOPEN(filename, "rb");
+	fp = VCWD_FOPEN(resolved_path, "rb");

 #ifndef PHP_WIN32
 	/* refuse to open anything that is not a regular file */
@@ -478,15 +480,20 @@
 #endif

 	if (!fp) {
+		if (SG(request_info).path_translated != filename) {
+			STR_FREE(filename);
+		}
 		STR_FREE(SG(request_info).path_translated);	/* for same reason as above */
 		SG(request_info).path_translated = NULL;
 		return FAILURE;
 	}

-	file_handle->opened_path = expand_filepath(filename, NULL TSRMLS_CC);
+	file_handle->opened_path = resolved_path;

-	STR_FREE(SG(request_info).path_translated);	/* for same reason as above */
-	SG(request_info).path_translated = filename;
+	if (SG(request_info).path_translated != filename) {
+		STR_FREE(SG(request_info).path_translated);	/* for same reason as above */
+		SG(request_info).path_translated = filename;
+	}

 	file_handle->filename = SG(request_info).path_translated;
 	file_handle->free_filename = 0;

Modified: php/php-src/trunk/main/fopen_wrappers.c
===================================================================
--- php/php-src/trunk/main/fopen_wrappers.c	2009-11-30 14:10:11 UTC (rev 291495)
+++ php/php-src/trunk/main/fopen_wrappers.c	2009-11-30 14:21:23 UTC (rev 291496)
@@ -338,16 +338,16 @@
 #ifndef PHP_WIN32
 	struct stat st;
 #endif
-	char *path_info, *filename;
+	char *path_info;
+	char *filename = NULL;
+	char *resolved_path = NULL;
 	int length;

-	filename = SG(request_info).path_translated;
 	path_info = SG(request_info).request_uri;
 #if HAVE_PWD_H
 	if (PG(user_dir) && *PG(user_dir) && path_info && '/' == path_info[0] && '~' == path_info[1]) {
 		char *s = strchr(path_info + 2, '/');

-		filename = NULL;	/* discard the original filename, it must not be used */
 		if (s) {			/* if there is no path name after the file, do not bother */
 			char user[32];			/* to try open the directory */
 			struct passwd *pw;
@@ -378,39 +378,41 @@
 #endif
 			if (pw && pw->pw_dir) {
 				spprintf(&filename, 0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */
-				STR_FREE(SG(request_info).path_translated);
-				SG(request_info).path_translated = filename;
-			}
+			} else {
+				filename = SG(request_info).path_translated;
+			}
 #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
 			efree(pwbuf);
 #endif
 		}
 	} else
 #endif
-	if (PG(doc_root) && path_info) {
-		length = strlen(PG(doc_root));
-		if (IS_ABSOLUTE_PATH(PG(doc_root), length)) {
-			filename = emalloc(length + strlen(path_info) + 2);
-			if (filename) {
-				memcpy(filename, PG(doc_root), length);
-				if (!IS_SLASH(filename[length - 1])) {	/* length is never 0 */
-					filename[length++] = PHP_DIR_SEPARATOR;
-				}
-				if (IS_SLASH(path_info[0])) {
-					length--;
-				}
-				strcpy(filename + length, path_info);
-				STR_FREE(SG(request_info).path_translated);
-				SG(request_info).path_translated = filename;
+	if (PG(doc_root) && path_info && (length = strlen(PG(doc_root)) &&
+		IS_ABSOLUTE_PATH(PG(doc_root), length))) {
+		filename = emalloc(length + strlen(path_info) + 2);
+		if (filename) {
+			memcpy(filename, PG(doc_root), length);
+			if (!IS_SLASH(filename[length - 1])) {	/* length is never 0 */
+				filename[length++] = PHP_DIR_SEPARATOR;
 			}
+			if (IS_SLASH(path_info[0])) {
+				length--;
+			}
+			strcpy(filename + length, path_info);
 		}
-	} /* if doc_root && path_info */
+	} else {
+		filename = SG(request_info).path_translated;
+	}

+
 	if (filename) {
-		filename = zend_resolve_path(filename, strlen(filename) TSRMLS_CC);
+		resolved_path = zend_resolve_path(filename, strlen(filename) TSRMLS_CC);
 	}

-	if (!filename) {
+	if (!resolved_path) {
+		if (SG(request_info).path_translated != filename) {
+			STR_FREE(filename);
+		}
 		/* we have to free SG(request_info).path_translated here because
 		 * php_destroy_request_info assumes that it will get
 		 * freed when the include_names hash is emptied, but
@@ -419,7 +421,7 @@
 		SG(request_info).path_translated = NULL;
 		return FAILURE;
 	}
-	fp = VCWD_FOPEN(filename, "rb");
+	fp = VCWD_FOPEN(resolved_path, "rb");

 #ifndef PHP_WIN32
 	/* refuse to open anything that is not a regular file */
@@ -430,15 +432,20 @@
 #endif

 	if (!fp) {
+		if (SG(request_info).path_translated != filename) {
+			STR_FREE(filename);
+		}
 		STR_FREE(SG(request_info).path_translated);	/* for same reason as above */
 		SG(request_info).path_translated = NULL;
 		return FAILURE;
 	}

-	file_handle->opened_path = expand_filepath(filename, NULL TSRMLS_CC);
+	file_handle->opened_path = resolved_path;

-	STR_FREE(SG(request_info).path_translated);	/* for same reason as above */
-	SG(request_info).path_translated = filename;
+	if (SG(request_info).path_translated != filename) {
+		STR_FREE(SG(request_info).path_translated);	/* for same reason as above */
+		SG(request_info).path_translated = filename;
+	}

 	file_handle->filename = SG(request_info).path_translated;
 	file_handle->free_filename = 0;
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to