summaryrefslogtreecommitdiff
path: root/main/fopen_wrappers.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/fopen_wrappers.c')
-rw-r--r--main/fopen_wrappers.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c
index 015be9703..d171ea9a3 100644
--- a/main/fopen_wrappers.c
+++ b/main/fopen_wrappers.c
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: fopen_wrappers.c 298277 2010-04-21 22:22:31Z felipe $ */
+/* $Id: fopen_wrappers.c 305698 2010-11-23 22:14:54Z pajoye $ */
/* {{{ includes
*/
@@ -173,21 +173,27 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path
memcpy(path_tmp, resolved_name, path_len + 1); /* safe */
while (VCWD_REALPATH(path_tmp, resolved_name) == NULL) {
-#ifdef HAVE_SYMLINK
- if (nesting_level == 0) {
- int ret;
- char buf[MAXPATHLEN];
-
- ret = readlink(path_tmp, buf, MAXPATHLEN - 1);
- if (ret < 0) {
- /* not a broken symlink, move along.. */
- } else {
- /* put the real path into the path buffer */
- memcpy(path_tmp, buf, ret);
- path_tmp[ret] = '\0';
+#if defined(PHP_WIN32) || defined(HAVE_SYMLINK)
+#if defined(PHP_WIN32)
+ if (EG(windows_version_info).dwMajorVersion > 5) {
+#endif
+ if (nesting_level == 0) {
+ int ret;
+ char buf[MAXPATHLEN];
+
+ ret = php_sys_readlink(path_tmp, buf, MAXPATHLEN - 1);
+ if (ret < 0) {
+ /* not a broken symlink, move along.. */
+ } else {
+ /* put the real path into the path buffer */
+ memcpy(path_tmp, buf, ret);
+ path_tmp[ret] = '\0';
+ }
}
+#if defined(PHP_WIN32)
}
#endif
+#endif
#if defined(PHP_WIN32) || defined(NETWARE)
path_file = strrchr(path_tmp, DEFAULT_SLASH);
@@ -228,6 +234,9 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path
resolved_basedir[resolved_basedir_len] = PHP_DIR_SEPARATOR;
resolved_basedir[++resolved_basedir_len] = '\0';
}
+ } else {
+ resolved_basedir[resolved_basedir_len++] = PHP_DIR_SEPARATOR;
+ resolved_basedir[resolved_basedir_len] = '\0';
}
resolved_name_len = strlen(resolved_name);
@@ -244,8 +253,13 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path
#else
if (strncmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
#endif
- /* File is in the right directory */
- return 0;
+ if (resolved_name_len > resolved_basedir_len &&
+ resolved_name[resolved_basedir_len - 1] != PHP_DIR_SEPARATOR) {
+ return -1;
+ } else {
+ /* File is in the right directory */
+ return 0;
+ }
} else {
/* /openbasedir/ and /openbasedir are the same directory */
if (resolved_basedir_len == (resolved_name_len + 1) && resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) {
@@ -281,6 +295,14 @@ PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC)
char *ptr;
char *end;
+ /* Check if the path is too long so we can give a more useful error
+ * message. */
+ if (strlen(path) > (MAXPATHLEN - 1)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "File name is longer than the maximum allowed path length on this platform (%d): %s", MAXPATHLEN, path);
+ errno = EINVAL;
+ return -1;
+ }
+
pathbuf = estrdup(PG(open_basedir));
ptr = pathbuf;
@@ -519,6 +541,10 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c
return NULL;
}
+ if (strlen(filename) != filename_length) {
+ return NULL;
+ }
+
/* Don't resolve paths which contain protocol (except of file://) */
for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) {