@@ -0,0 +1,2625 @@
+diff -Nura php-5.2.5/TSRM/TSRM.h suhosin-patch-5.2.5-0.9.6.2/TSRM/TSRM.h
+--- php-5.2.5/TSRM/TSRM.h 2007-04-17 06:26:32.000000000 +0000
++++ suhosin-patch-5.2.5-0.9.6.2/TSRM/TSRM.h 2007-11-10 09:57:11.000000000 +0000
+@@ -38,6 +38,13 @@
+ typedef unsigned long tsrm_uintptr_t;
+ #endif
+
++#if SUHOSIN_PATCH
++# if HAVE_REALPATH
++# undef realpath
++# define realpath php_realpath
++# endif
++#endif
++
+ /* Only compile multi-threading functions if we're in ZTS mode */
+ #ifdef ZTS
+
+@@ -93,6 +100,7 @@
+
+ #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
+
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+diff -Nura php-5.2.5/TSRM/tsrm_virtual_cwd.c suhosin-patch-5.2.5-0.9.6.2/TSRM/tsrm_virtual_cwd.c
+--- php-5.2.5/TSRM/tsrm_virtual_cwd.c 2007-10-23 05:57:35.000000000 +0000
++++ suhosin-patch-5.2.5-0.9.6.2/TSRM/tsrm_virtual_cwd.c 2007-11-10 09:57:11.000000000 +0000
+@@ -273,6 +273,177 @@
+ }
+ /* }}} */
+
++#if SUHOSIN_PATCH
++CWD_API char *php_realpath(const char *path, char *resolved)
++{
++ struct stat sb;
++ char *p, *q, *s;
++ size_t left_len, resolved_len;
++ unsigned symlinks;
++ int serrno, slen;
++ int is_dir = 1;
++ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
++
++ serrno = errno;
++ symlinks = 0;
++ if (path[0] == '/') {
++ resolved[0] = '/';
++ resolved[1] = '\0';
++ if (path[1] == '\0')
++ return (resolved);
++ resolved_len = 1;
++ left_len = strlcpy(left, path + 1, sizeof(left));
++ } else {
++ if (getcwd(resolved, PATH_MAX) == NULL) {
++ strlcpy(resolved, ".", PATH_MAX);
++ return (NULL);
++ }
++ resolved_len = strlen(resolved);
++ left_len = strlcpy(left, path, sizeof(left));
++ }
++ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
++ errno = ENAMETOOLONG;
++ return (NULL);
++ }
++
++ /*
++ * Iterate over path components in `left'.
++ */
++ while (left_len != 0) {
++ /*
++ * Extract the next path component and adjust `left'
++ * and its length.
++ */
++ p = strchr(left, '/');
++ s = p ? p : left + left_len;
++ if (s - left >= sizeof(next_token)) {
++ errno = ENAMETOOLONG;
++ return (NULL);
++ }
++ memcpy(next_token, left, s - left);
++ next_token[s - left] = '\0';
++ left_len -= s - left;
++ if (p != NULL)
++ memmove(left, s + 1, left_len + 1);
++ if (resolved[resolved_len - 1] != '/') {
++ if (resolved_len + 1 >= PATH_MAX) {
++ errno = ENAMETOOLONG;
++ return (NULL);
++ }
++ resolved[resolved_len++] = '/';
++ resolved[resolved_len] = '\0';
++ }
++ if (next_token[0] == '\0')
++ continue;
++ else if (strcmp(next_token, ".") == 0)
++ continue;
++ else if (strcmp(next_token, "..") == 0) {
++ /*
++ * Strip the last path component except when we have
++ * single "/"
++ */
++ if (!is_dir) {
++ errno = ENOENT;
++ return (NULL);
++ }
++ if (resolved_len > 1) {
++ resolved[resolved_len - 1] = '\0';
++ q = strrchr(resolved, '/');
++ *q = '\0';
++ resolved_len = q - resolved;
++ }
++ continue;
++ }
++
++ /*
++ * Append the next path component and lstat() it. If
++ * lstat() fails we still can return successfully if
++ * there are no more path components left.
++ */
++ resolved_len = strlcat(resolved, next_token, PATH_MAX);
++ if (resolved_len >= PATH_MAX) {
++ errno = ENAMETOOLONG;
++ return (NULL);
++ }
++ if (lstat(resolved, &sb) != 0) {
++ if (errno == ENOENT) {
++ if (p == NULL) {
++ errno = serrno;
++ return (resolved);
++ } else if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) {
++ resolved_len = strlcat(resolved, "/", PATH_MAX);
++ resolved_len = strlcat(resolved, left, PATH_MAX);
++ if (resolved_len >= PATH_MAX) {
++ errno = ENAMETOOLONG;
++ return (NULL);
++ }
++ errno = serrno;
++ return (resolved);
++ }
++ }
++ return (NULL);
++ }
++ if (S_ISLNK(sb.st_mode)) {
++ if (symlinks++ > MAXSYMLINKS) {
++ errno = ELOOP;
++ return (NULL);
++ }
++ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
++ if (slen < 0)
++ return (NULL);
++ symlink[slen] = '\0';
++ if (symlink[0] == '/') {
++ resolved[1] = 0;
++ resolved_len = 1;
++ } else if (resolved_len > 1) {
++ /* Strip the last path component. */
++ resolved[resolved_len - 1] = '\0';
++ q = strrchr(resolved, '/');
++ *q = '\0';
++ resolved_len = q - resolved;
++ }
++
++ /*
++ * If there are any path components left, then
++ * append them to symlink. The result is placed
++ * in `left'.
++ */
++ if (p != NULL) {
++ if (symlink[slen - 1] != '/') {
++ if (slen + 1 >= sizeof(symlink)) {
++ errno = ENAMETOOLONG;
++ return (NULL);
++ }
++ symlink[slen] = '/';
++ symlink[slen + 1] = 0;
++ }
++ left_len = strlcat(symlink, left, sizeof(left));
++ if (left_len >= sizeof(left)) {
++ errno = ENAMETOOLONG;
++ return (NULL);
++ }
++ }
++ left_len = strlcpy(left, symlink, sizeof(left));
++ } else {
++ if (S_ISDIR(sb.st_mode)) {
++ is_dir = 1;
++ } else {
++ is_dir = 0;
++ }
++ }
++ }
++
++ /*
++ * Remove trailing slash except when the resolved pathname
++ * is a single "/".
++ */
++ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
++ resolved[resolved_len - 1] = '\0';
++ return (resolved);
|