applied and fixed the original patch

initial work on the patch import done
This commit is contained in:
Anatol Belski 2013-10-17 10:40:43 +02:00
parent e30b2aae5a
commit cf6ab0e915
9 changed files with 106 additions and 79 deletions

View file

@ -30,6 +30,7 @@
#include "zend_ini.h" #include "zend_ini.h"
#include "zend_vm.h" #include "zend_vm.h"
#include "zend_dtrace.h" #include "zend_dtrace.h"
#include "zend_virtual_cwd.h"
#ifdef ZTS #ifdef ZTS
# define GLOBAL_FUNCTION_TABLE global_function_table # define GLOBAL_FUNCTION_TABLE global_function_table
@ -652,6 +653,8 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS
start_memory_manager(TSRMLS_C); start_memory_manager(TSRMLS_C);
virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */
#if defined(__FreeBSD__) || defined(__DragonFly__) #if defined(__FreeBSD__) || defined(__DragonFly__)
/* FreeBSD and DragonFly floating point precision fix */ /* FreeBSD and DragonFly floating point precision fix */
fpsetmask(0); fpsetmask(0);
@ -802,9 +805,14 @@ void zend_post_startup(TSRMLS_D) /* {{{ */
compiler_globals_ctor(compiler_globals, tsrm_ls); compiler_globals_ctor(compiler_globals, tsrm_ls);
} }
free(EG(zend_constants)); free(EG(zend_constants));
virtual_cwd_deactivate(TSRMLS_C);
executor_globals_ctor(executor_globals, tsrm_ls); executor_globals_ctor(executor_globals, tsrm_ls);
global_persistent_list = &EG(persistent_list); global_persistent_list = &EG(persistent_list);
zend_copy_ini_directives(TSRMLS_C); zend_copy_ini_directives(TSRMLS_C);
#else
virtual_cwd_deactivate(TSRMLS_C);
#endif #endif
} }
/* }}} */ /* }}} */
@ -820,6 +828,9 @@ void zend_shutdown(TSRMLS_D) /* {{{ */
zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC); zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
zend_destroy_modules(); zend_destroy_modules();
virtual_cwd_deactivate(TSRMLS_C);
virtual_cwd_shutdown();
zend_hash_destroy(GLOBAL_FUNCTION_TABLE); zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
zend_hash_destroy(GLOBAL_CLASS_TABLE); zend_hash_destroy(GLOBAL_CLASS_TABLE);
@ -910,6 +921,7 @@ ZEND_API char *get_zend_version(void) /* {{{ */
void zend_activate(TSRMLS_D) /* {{{ */ void zend_activate(TSRMLS_D) /* {{{ */
{ {
virtual_cwd_activate(TSRMLS_C);
gc_reset(TSRMLS_C); gc_reset(TSRMLS_C);
init_compiler(TSRMLS_C); init_compiler(TSRMLS_C);
init_executor(TSRMLS_C); init_executor(TSRMLS_C);

View file

@ -30,6 +30,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
#include "zend.h"
#include "zend_virtual_cwd.h" #include "zend_virtual_cwd.h"
#include "tsrm_strtok_r.h" #include "tsrm_strtok_r.h"
@ -149,11 +150,12 @@ static int php_check_dots(const char *element, int n)
#define CWD_STATE_COPY(d, s) \ #define CWD_STATE_COPY(d, s) \
(d)->cwd_length = (s)->cwd_length; \ (d)->cwd_length = (s)->cwd_length; \
(d)->cwd = (char *) malloc((s)->cwd_length+1); \ (d)->cwd = (char *) emalloc((s)->cwd_length+1); \
memcpy((d)->cwd, (s)->cwd, (s)->cwd_length+1); memcpy((d)->cwd, (s)->cwd, (s)->cwd_length+1);
#define CWD_STATE_FREE(s) \ #define CWD_STATE_FREE(s) \
free((s)->cwd); efree((s)->cwd); \
(s)->cwd = NULL;
#ifdef TSRM_WIN32 #ifdef TSRM_WIN32
@ -337,16 +339,15 @@ CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{
HANDLE hLink = NULL; HANDLE hLink = NULL;
REPARSE_DATA_BUFFER * pbuffer; REPARSE_DATA_BUFFER * pbuffer;
unsigned int retlength = 0; unsigned int retlength = 0;
TSRM_ALLOCA_FLAG(use_heap_large);
hLink = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); hLink = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL);
if(hLink == INVALID_HANDLE_VALUE) { if(hLink == INVALID_HANDLE_VALUE) {
return -1; return -1;
} }
pbuffer = (REPARSE_DATA_BUFFER *)tsrm_do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); pbuffer = (REPARSE_DATA_BUFFER *)emalloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) { if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) {
tsrm_free_alloca(pbuffer, use_heap_large); efree(pbuffer);
CloseHandle(hLink); CloseHandle(hLink);
return -1; return -1;
} }
@ -363,7 +364,7 @@ CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{
buf->st_mode |=; buf->st_mode |=;
} }
#endif #endif
tsrm_free_alloca(pbuffer, use_heap_large); efree(pbuffer);
} else { } else {
buf->st_mode = (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? (S_IFDIR|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)) : S_IFREG; buf->st_mode = (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? (S_IFDIR|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)) : S_IFREG;
buf->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6)); buf->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6));
@ -424,12 +425,13 @@ static void cwd_globals_ctor(virtual_cwd_globals *cwd_g TSRMLS_DC) /* {{{ */
cwd_g->realpath_cache_size_limit = REALPATH_CACHE_SIZE; cwd_g->realpath_cache_size_limit = REALPATH_CACHE_SIZE;
cwd_g->realpath_cache_ttl = REALPATH_CACHE_TTL; cwd_g->realpath_cache_ttl = REALPATH_CACHE_TTL;
memset(cwd_g->realpath_cache, 0, sizeof(cwd_g->realpath_cache)); memset(cwd_g->realpath_cache, 0, sizeof(cwd_g->realpath_cache));
virtual_cwd_activate(TSRMLS_C);
} }
/* }}} */ /* }}} */
static void cwd_globals_dtor(virtual_cwd_globals *cwd_g TSRMLS_DC) /* {{{ */ static void cwd_globals_dtor(virtual_cwd_globals *cwd_g TSRMLS_DC) /* {{{ */
{ {
CWD_STATE_FREE(&cwd_g->cwd); /* CWD_STATE_FREE(&cwd_globals->cwd); */
realpath_cache_clean(TSRMLS_C); realpath_cache_clean(TSRMLS_C);
} }
/* }}} */ /* }}} */
@ -490,6 +492,24 @@ CWD_API void virtual_cwd_shutdown(void) /* {{{ */
} }
/* }}} */ /* }}} */
CWD_API int virtual_cwd_activate(TSRMLS_D) /* {{{ */
{
if (CWDG(cwd).cwd == NULL) {
CWD_STATE_COPY(&CWDG(cwd), &main_cwd_state);
}
return 0;
}
/* }}} */
CWD_API int virtual_cwd_deactivate(TSRMLS_D) /* {{{ */
{
if (CWDG(cwd).cwd != NULL) {
CWD_STATE_FREE(&CWDG(cwd));
}
return 0;
}
/* }}} */
CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */
{ {
cwd_state *state; cwd_state *state;
@ -500,7 +520,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */
char *retval; char *retval;
*length = 1; *length = 1;
retval = (char *) malloc(2); retval = (char *) emalloc(2);
if (retval == NULL) { if (retval == NULL) {
return NULL; return NULL;
} }
@ -515,7 +535,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */
char *retval; char *retval;
*length = state->cwd_length+1; *length = state->cwd_length+1;
retval = (char *) malloc(*length+1); retval = (char *) emalloc(*length+1);
if (retval == NULL) { if (retval == NULL) {
return NULL; return NULL;
} }
@ -527,7 +547,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */
} }
#endif #endif
*length = state->cwd_length; *length = state->cwd_length;
return strdup(state->cwd); return estrdup(state->cwd);
} }
/* }}} */ /* }}} */
@ -543,12 +563,12 @@ CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC) /* {{{ */
return cwd; return cwd;
} }
if (length > size-1) { if (length > size-1) {
free(cwd); efree(cwd);
errno = ERANGE; /* Is this OK? */ errno = ERANGE; /* Is this OK? */
return NULL; return NULL;
} }
memcpy(buf, cwd, length+1); memcpy(buf, cwd, length+1);
free(cwd); efree(cwd);
return buf; return buf;
} }
/* }}} */ /* }}} */
@ -754,13 +774,11 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
#ifdef TSRM_WIN32 #ifdef TSRM_WIN32
WIN32_FIND_DATA data; WIN32_FIND_DATA data;
HANDLE hFind; HANDLE hFind;
TSRM_ALLOCA_FLAG(use_heap_large)
#else #else
struct stat st; struct stat st;
#endif #endif
realpath_cache_bucket *bucket; realpath_cache_bucket *bucket;
char *tmp; char *tmp;
TSRM_ALLOCA_FLAG(use_heap)
while (1) { while (1) {
if (len <= start) { if (len <= start) {
@ -860,7 +878,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
FindClose(hFind); FindClose(hFind);
} }
tmp = tsrm_do_alloca(len+1, use_heap); tmp = emalloc(len+1);
memcpy(tmp, path, len+1); memcpy(tmp, path, len+1);
if(save && if(save &&
@ -887,12 +905,12 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
return -1; return -1;
} }
pbuffer = (REPARSE_DATA_BUFFER *)tsrm_do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); pbuffer = (REPARSE_DATA_BUFFER *)emalloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
if (pbuffer == NULL) { if (pbuffer == NULL) {
return -1; return -1;
} }
if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) { if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) {
tsrm_free_alloca(pbuffer, use_heap_large); efree(pbuffer);
CloseHandle(hLink); CloseHandle(hLink);
return -1; return -1;
} }
@ -908,7 +926,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
printname_len + 1, printname_len + 1,
printname, MAX_PATH, NULL, NULL printname, MAX_PATH, NULL, NULL
)) { )) {
tsrm_free_alloca(pbuffer, use_heap_large); efree(pbuffer);
return -1; return -1;
}; };
printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR); printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
@ -920,7 +938,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
substitutename_len + 1, substitutename_len + 1,
substitutename, MAX_PATH, NULL, NULL substitutename, MAX_PATH, NULL, NULL
)) { )) {
tsrm_free_alloca(pbuffer, use_heap_large); efree(pbuffer);
return -1; return -1;
}; };
substitutename[substitutename_len] = 0; substitutename[substitutename_len] = 0;
@ -934,7 +952,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
printname_len + 1, printname_len + 1,
printname, MAX_PATH, NULL, NULL printname, MAX_PATH, NULL, NULL
)) { )) {
tsrm_free_alloca(pbuffer, use_heap_large); efree(pbuffer);
return -1; return -1;
}; };
printname[pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR)] = 0; printname[pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR)] = 0;
@ -945,7 +963,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
substitutename_len + 1, substitutename_len + 1,
substitutename, MAX_PATH, NULL, NULL substitutename, MAX_PATH, NULL, NULL
)) { )) {
tsrm_free_alloca(pbuffer, use_heap_large); efree(pbuffer);
return -1; return -1;
}; };
substitutename[substitutename_len] = 0; substitutename[substitutename_len] = 0;
@ -955,7 +973,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
memcpy(substitutename, path, len + 1); memcpy(substitutename, path, len + 1);
substitutename_len = len; substitutename_len = len;
} else { } else {
tsrm_free_alloca(pbuffer, use_heap_large); efree(pbuffer);
return -1; return -1;
} }
@ -999,21 +1017,21 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
fprintf(stderr, "sub: %s ", substitutename); fprintf(stderr, "sub: %s ", substitutename);
fprintf(stderr, "resolved: %s ", path); fprintf(stderr, "resolved: %s ", path);
#endif #endif
tsrm_free_alloca(pbuffer, use_heap_large); efree(pbuffer);
if(isabsolute == 1) { if(isabsolute == 1) {
if (!((j == 3) && (path[1] == ':') && (path[2] == '\\'))) { if (!((j == 3) && (path[1] == ':') && (path[2] == '\\'))) {
/* use_realpath is 0 in the call below coz path is absolute*/ /* use_realpath is 0 in the call below coz path is absolute*/
j = tsrm_realpath_r(path, 0, j, ll, t, 0, is_dir, &directory TSRMLS_CC); j = tsrm_realpath_r(path, 0, j, ll, t, 0, is_dir, &directory TSRMLS_CC);
if(j < 0) { if(j < 0) {
tsrm_free_alloca(tmp, use_heap); efree(tmp);
return -1; return -1;
} }
} }
} }
else { else {
if(i + j >= MAXPATHLEN - 1) { if(i + j >= MAXPATHLEN - 1) {
tsrm_free_alloca(tmp, use_heap); efree(tmp);
return -1; return -1;
} }
@ -1022,7 +1040,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
path[i-1] = DEFAULT_SLASH; path[i-1] = DEFAULT_SLASH;
j = tsrm_realpath_r(path, start, i + j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC); j = tsrm_realpath_r(path, start, i + j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC);
if(j < 0) { if(j < 0) {
tsrm_free_alloca(tmp, use_heap); efree(tmp);
return -1; return -1;
} }
} }
@ -1043,7 +1061,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
#elif defined(NETWARE) #elif defined(NETWARE)
save = 0; save = 0;
tmp = tsrm_do_alloca(len+1, use_heap); tmp = emalloc(len+1);
memcpy(tmp, path, len+1); memcpy(tmp, path, len+1);
#else #else
if (save && php_sys_lstat(path, &st) < 0) { if (save && php_sys_lstat(path, &st) < 0) {
@ -1055,25 +1073,25 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
save = 0; save = 0;
} }
tmp = tsrm_do_alloca(len+1, use_heap); tmp = emalloc(len+1);
memcpy(tmp, path, len+1); memcpy(tmp, path, len+1);
if (save && S_ISLNK(st.st_mode)) { if (save && S_ISLNK(st.st_mode)) {
if (++(*ll) > LINK_MAX || (j = php_sys_readlink(tmp, path, MAXPATHLEN)) < 0) { if (++(*ll) > LINK_MAX || (j = php_sys_readlink(tmp, path, MAXPATHLEN)) < 0) {
/* too many links or broken symlinks */ /* too many links or broken symlinks */
tsrm_free_alloca(tmp, use_heap); efree(tmp);
return -1; return -1;
} }
path[j] = 0; path[j] = 0;
if (IS_ABSOLUTE_PATH(path, j)) { if (IS_ABSOLUTE_PATH(path, j)) {
j = tsrm_realpath_r(path, 1, j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC); j = tsrm_realpath_r(path, 1, j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC);
if (j < 0) { if (j < 0) {
tsrm_free_alloca(tmp, use_heap); efree(tmp);
return -1; return -1;
} }
} else { } else {
if (i + j >= MAXPATHLEN-1) { if (i + j >= MAXPATHLEN-1) {
tsrm_free_alloca(tmp, use_heap); efree(tmp);
return -1; /* buffer overflow */ return -1; /* buffer overflow */
} }
memmove(path+i, path, j+1); memmove(path+i, path, j+1);
@ -1081,7 +1099,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
path[i-1] = DEFAULT_SLASH; path[i-1] = DEFAULT_SLASH;
j = tsrm_realpath_r(path, start, i + j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC); j = tsrm_realpath_r(path, start, i + j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC);
if (j < 0) { if (j < 0) {
tsrm_free_alloca(tmp, use_heap); efree(tmp);
return -1; return -1;
} }
} }
@ -1096,7 +1114,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
} }
if (is_dir && !directory) { if (is_dir && !directory) {
/* not a directory */ /* not a directory */
tsrm_free_alloca(tmp, use_heap); efree(tmp);
return -1; return -1;
} }
} }
@ -1112,7 +1130,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
} }
#ifdef TSRM_WIN32 #ifdef TSRM_WIN32
if (j < 0 || j + len - i >= MAXPATHLEN-1) { if (j < 0 || j + len - i >= MAXPATHLEN-1) {
tsrm_free_alloca(tmp, use_heap); efree(tmp);
return -1; return -1;
} }
if (save) { if (save) {
@ -1127,7 +1145,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
} }
#else #else
if (j < 0 || j + len - i >= MAXPATHLEN-1) { if (j < 0 || j + len - i >= MAXPATHLEN-1) {
tsrm_free_alloca(tmp, use_heap); efree(tmp);
return -1; return -1;
} }
memcpy(path+j, tmp+i, len-i+1); memcpy(path+j, tmp+i, len-i+1);
@ -1140,7 +1158,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
realpath_cache_add(tmp, len, path, j, directory, *t TSRMLS_CC); realpath_cache_add(tmp, len, path, j, directory, *t TSRMLS_CC);
} }
tsrm_free_alloca(tmp, use_heap); efree(tmp);
return j; return j;
} }
} }
@ -1316,7 +1334,7 @@ verify:
CWD_STATE_COPY(&old_state, state); CWD_STATE_COPY(&old_state, state);
state->cwd_length = path_length; state->cwd_length = path_length;
tmp = realloc(state->cwd, state->cwd_length+1); tmp = erealloc(state->cwd, state->cwd_length+1);
if (tmp == NULL) { if (tmp == NULL) {
#if VIRTUAL_CWD_DEBUG #if VIRTUAL_CWD_DEBUG
fprintf (stderr, "Out of memory\n"); fprintf (stderr, "Out of memory\n");
@ -1336,7 +1354,7 @@ verify:
} }
} else { } else {
state->cwd_length = path_length; state->cwd_length = path_length;
tmp = realloc(state->cwd, state->cwd_length+1); tmp = erealloc(state->cwd, state->cwd_length+1);
if (tmp == NULL) { if (tmp == NULL) {
#if VIRTUAL_CWD_DEBUG #if VIRTUAL_CWD_DEBUG
fprintf (stderr, "Out of memory\n"); fprintf (stderr, "Out of memory\n");
@ -1367,7 +1385,6 @@ CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path
int length = strlen(path); int length = strlen(path);
char *temp; char *temp;
int retval; int retval;
TSRM_ALLOCA_FLAG(use_heap)
if (length == 0) { if (length == 0) {
return 1; /* Can't cd to empty string */ return 1; /* Can't cd to empty string */
@ -1384,14 +1401,14 @@ CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path
if (length == COPY_WHEN_ABSOLUTE(path) && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */ if (length == COPY_WHEN_ABSOLUTE(path) && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */
length++; length++;
} }
temp = (char *) tsrm_do_alloca(length+1, use_heap); temp = (char *) emalloc(length+1);
memcpy(temp, path, length); memcpy(temp, path, length);
temp[length] = 0; temp[length] = 0;
#if VIRTUAL_CWD_DEBUG #if VIRTUAL_CWD_DEBUG
fprintf (stderr, "Changing directory to %s\n", temp); fprintf (stderr, "Changing directory to %s\n", temp);
#endif #endif
retval = p_chdir(temp TSRMLS_CC); retval = p_chdir(temp TSRMLS_CC);
tsrm_free_alloca(temp, use_heap); efree(temp);
return retval; return retval;
} }
/* }}} */ /* }}} */
@ -1404,7 +1421,7 @@ CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC) /* {
/* realpath("") returns CWD */ /* realpath("") returns CWD */
if (!*path) { if (!*path) {
new_state.cwd = (char*)malloc(1); new_state.cwd = (char*)emalloc(1);
if (new_state.cwd == NULL) { if (new_state.cwd == NULL) {
retval = NULL; retval = NULL;
goto end; goto end;
@ -1417,7 +1434,7 @@ CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC) /* {
} else if (!IS_ABSOLUTE_PATH(path, strlen(path))) { } else if (!IS_ABSOLUTE_PATH(path, strlen(path))) {
CWD_STATE_COPY(&new_state, &CWDG(cwd)); CWD_STATE_COPY(&new_state, &CWDG(cwd));
} else { } else {
new_state.cwd = (char*)malloc(1); new_state.cwd = (char*)emalloc(1);
if (new_state.cwd == NULL) { if (new_state.cwd == NULL) {
retval = NULL; retval = NULL;
goto end; goto end;
@ -1882,7 +1899,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) /*
dir_length = CWDG(cwd).cwd_length; dir_length = CWDG(cwd).cwd_length;
dir = CWDG(cwd).cwd; dir = CWDG(cwd).cwd;
ptr = command_line = (char *) malloc(command_length + sizeof("cd '' ; ") + dir_length + extra+1+1); ptr = command_line = (char *) emalloc(command_length + sizeof("cd '' ; ") + dir_length + extra+1+1);
if (!command_line) { if (!command_line) {
return NULL; return NULL;
} }
@ -1916,7 +1933,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) /*
memcpy(ptr, command, command_length+1); memcpy(ptr, command, command_length+1);
retval = popen(command_line, type); retval = popen(command_line, type);
free(command_line); efree(command_line);
return retval; return retval;
} }
/* }}} */ /* }}} */
@ -1929,7 +1946,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{
/* realpath("") returns CWD */ /* realpath("") returns CWD */
if (!*path) { if (!*path) {
new_state.cwd = (char*)malloc(1); new_state.cwd = (char*)emalloc(1);
if (new_state.cwd == NULL) { if (new_state.cwd == NULL) {
return NULL; return NULL;
} }
@ -1940,10 +1957,10 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{
} }
} else if (!IS_ABSOLUTE_PATH(path, strlen(path)) && } else if (!IS_ABSOLUTE_PATH(path, strlen(path)) &&
VCWD_GETCWD(cwd, MAXPATHLEN)) { VCWD_GETCWD(cwd, MAXPATHLEN)) {
new_state.cwd = strdup(cwd); new_state.cwd = estrdup(cwd);
new_state.cwd_length = strlen(cwd); new_state.cwd_length = strlen(cwd);
} else { } else {
new_state.cwd = (char*)malloc(1); new_state.cwd = (char*)emalloc(1);
if (new_state.cwd == NULL) { if (new_state.cwd == NULL) {
return NULL; return NULL;
} }
@ -1952,7 +1969,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{
} }
if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) { if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) {
free(new_state.cwd); efree(new_state.cwd);
return NULL; return NULL;
} }
@ -1960,7 +1977,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{
int copy_len = new_state.cwd_length>MAXPATHLEN-1 ? MAXPATHLEN-1 : new_state.cwd_length; int copy_len = new_state.cwd_length>MAXPATHLEN-1 ? MAXPATHLEN-1 : new_state.cwd_length;
memcpy(real_path, new_state.cwd, copy_len); memcpy(real_path, new_state.cwd, copy_len);
real_path[copy_len] = '\0'; real_path[copy_len] = '\0';
free(new_state.cwd); efree(new_state.cwd);
return real_path; return real_path;
} else { } else {
return new_state.cwd; return new_state.cwd;

View file

@ -151,6 +151,8 @@ typedef int (*verify_path_func)(const cwd_state *);
CWD_API void virtual_cwd_startup(void); CWD_API void virtual_cwd_startup(void);
CWD_API void virtual_cwd_shutdown(void); CWD_API void virtual_cwd_shutdown(void);
CWD_API int virtual_cwd_activate(TSRMLS_D);
CWD_API int virtual_cwd_deactivate(TSRMLS_D);
CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC); CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC);
CWD_API int virtual_chdir(const char *path TSRMLS_DC); CWD_API int virtual_chdir(const char *path TSRMLS_DC);

View file

@ -154,7 +154,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
size_t path_cleaned_len; size_t path_cleaned_len;
cwd_state new_state; cwd_state new_state;
new_state.cwd = (char*)malloc(1); new_state.cwd = (char*)emalloc(1);
new_state.cwd[0] = '\0'; new_state.cwd[0] = '\0';
new_state.cwd_length = 0; new_state.cwd_length = 0;
@ -191,7 +191,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) { if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) {
efree(file_dirname_fullpath); efree(file_dirname_fullpath);
efree(file_basename); efree(file_basename);
free(new_state.cwd); efree(new_state.cwd);
return 0; return 0;
} }
} }
@ -215,7 +215,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
efree(file_dirname_fullpath); efree(file_dirname_fullpath);
if (!is_dir_only) { if (!is_dir_only) {
efree(file_basename); efree(file_basename);
free(new_state.cwd); efree(new_state.cwd);
} }
return 0; return 0;
} }
@ -224,7 +224,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
/* it is a standalone directory, job done */ /* it is a standalone directory, job done */
if (is_dir_only) { if (is_dir_only) {
efree(file_dirname_fullpath); efree(file_dirname_fullpath);
free(new_state.cwd); efree(new_state.cwd);
return 1; return 1;
} }
@ -232,13 +232,13 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
if (!len) { if (!len) {
efree(file_dirname_fullpath); efree(file_dirname_fullpath);
efree(file_basename); efree(file_basename);
free(new_state.cwd); efree(new_state.cwd);
return 0; return 0;
} else if (len > MAXPATHLEN) { } else if (len > MAXPATHLEN) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN);
efree(file_dirname_fullpath); efree(file_dirname_fullpath);
efree(file_basename); efree(file_basename);
free(new_state.cwd); efree(new_state.cwd);
return 0; return 0;
} }
@ -250,7 +250,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
efree(fullpath); efree(fullpath);
efree(file_dirname_fullpath); efree(file_dirname_fullpath);
efree(file_basename); efree(file_basename);
free(new_state.cwd); efree(new_state.cwd);
return 0; return 0;
} }
@ -285,7 +285,7 @@ done:
efree(fullpath); efree(fullpath);
efree(file_basename); efree(file_basename);
efree(file_dirname_fullpath); efree(file_dirname_fullpath);
free(new_state.cwd); efree(new_state.cwd);
if (n<0) { if (n<0) {
return 0; return 0;

View file

@ -91,8 +91,6 @@ SAPI_API void sapi_startup(sapi_module_struct *sf)
sapi_globals_ctor(&sapi_globals); sapi_globals_ctor(&sapi_globals);
#endif #endif
virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */
#ifdef PHP_WIN32 #ifdef PHP_WIN32
tsrm_win32_startup(); tsrm_win32_startup();
#endif #endif
@ -110,8 +108,6 @@ SAPI_API void sapi_shutdown(void)
reentrancy_shutdown(); reentrancy_shutdown();
virtual_cwd_shutdown();
#ifdef PHP_WIN32 #ifdef PHP_WIN32
tsrm_win32_shutdown(); tsrm_win32_shutdown();
#endif #endif

View file

@ -791,11 +791,11 @@ PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, co
} }
} }
new_state.cwd = strdup(cwd); new_state.cwd = estrdup(cwd);
new_state.cwd_length = strlen(cwd); new_state.cwd_length = strlen(cwd);
if (virtual_file_ex(&new_state, filepath, NULL, realpath_mode TSRMLS_CC)) { if (virtual_file_ex(&new_state, filepath, NULL, realpath_mode TSRMLS_CC)) {
free(new_state.cwd); efree(new_state.cwd);
return NULL; return NULL;
} }
@ -806,7 +806,7 @@ PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, co
} else { } else {
real_path = estrndup(new_state.cwd, new_state.cwd_length); real_path = estrndup(new_state.cwd, new_state.cwd_length);
} }
free(new_state.cwd); efree(new_state.cwd);
return real_path; return real_path;
} }

View file

@ -1816,6 +1816,9 @@ void php_request_shutdown(void *dummy)
sapi_deactivate(TSRMLS_C); sapi_deactivate(TSRMLS_C);
} zend_end_try(); } zend_end_try();
/* 9.5 free virtual CWD memory */
virtual_cwd_deactivate(TSRMLS_C);
/* 10. Destroy stream hashes */ /* 10. Destroy stream hashes */
zend_try { zend_try {
php_shutdown_stream_hashes(TSRMLS_C); php_shutdown_stream_hashes(TSRMLS_C);
@ -2243,9 +2246,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
} }
#endif #endif
#ifdef ZTS
zend_post_startup(TSRMLS_C); zend_post_startup(TSRMLS_C);
#endif
module_initialized = 1; module_initialized = 1;
@ -2315,6 +2316,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
shutdown_memory_manager(1, 0 TSRMLS_CC); shutdown_memory_manager(1, 0 TSRMLS_CC);
zend_interned_strings_snapshot(TSRMLS_C); zend_interned_strings_snapshot(TSRMLS_C);
virtual_cwd_activate(TSRMLS_C);
/* we're done */ /* we're done */
return retval; return retval;
@ -2410,14 +2412,13 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
volatile int old_cwd_fd = -1; volatile int old_cwd_fd = -1;
#else #else
char *old_cwd; char *old_cwd;
ALLOCA_FLAG(use_heap)
#endif #endif
int retval = 0; int retval = 0;
EG(exit_status) = 0; EG(exit_status) = 0;
#ifndef HAVE_BROKEN_GETCWD #ifndef HAVE_BROKEN_GETCWD
# define OLD_CWD_SIZE 4096 # define OLD_CWD_SIZE 4096
old_cwd = do_alloca(OLD_CWD_SIZE, use_heap); old_cwd = emalloc(OLD_CWD_SIZE);
old_cwd[0] = '\0'; old_cwd[0] = '\0';
#endif #endif
@ -2498,7 +2499,7 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
if (old_cwd[0] != '\0') { if (old_cwd[0] != '\0') {
php_ignore_value(VCWD_CHDIR(old_cwd)); php_ignore_value(VCWD_CHDIR(old_cwd));
} }
free_alloca(old_cwd, use_heap); efree(old_cwd);
#endif #endif
return retval; return retval;
} }
@ -2509,11 +2510,10 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval **ret TSRMLS_DC) PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval **ret TSRMLS_DC)
{ {
char *old_cwd; char *old_cwd;
ALLOCA_FLAG(use_heap)
EG(exit_status) = 0; EG(exit_status) = 0;
#define OLD_CWD_SIZE 4096 #define OLD_CWD_SIZE 4096
old_cwd = do_alloca(OLD_CWD_SIZE, use_heap); old_cwd = emalloc(OLD_CWD_SIZE);
old_cwd[0] = '\0'; old_cwd[0] = '\0';
zend_try { zend_try {
@ -2536,7 +2536,7 @@ PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval **ret
php_ignore_value(VCWD_CHDIR(old_cwd)); php_ignore_value(VCWD_CHDIR(old_cwd));
} }
free_alloca(old_cwd, use_heap); efree(old_cwd);
return EG(exit_status); return EG(exit_status);
} }
/* }}} */ /* }}} */

View file

@ -124,11 +124,11 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char **
cwd[0] = '\0'; cwd[0] = '\0';
} }
new_state.cwd = strdup(cwd); new_state.cwd = estrdup(cwd);
new_state.cwd_length = strlen(cwd); new_state.cwd_length = strlen(cwd);
if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) { if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) {
free(new_state.cwd); efree(new_state.cwd);
return -1; return -1;
} }
@ -140,7 +140,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char **
if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) >= MAXPATHLEN) { if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) >= MAXPATHLEN) {
efree(opened_path); efree(opened_path);
free(new_state.cwd); efree(new_state.cwd);
return -1; return -1;
} }
@ -151,7 +151,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char **
* which means that opening it will fail... */ * which means that opening it will fail... */
if (VCWD_CHMOD(opened_path, 0600)) { if (VCWD_CHMOD(opened_path, 0600)) {
efree(opened_path); efree(opened_path);
free(new_state.cwd); efree(new_state.cwd);
return -1; return -1;
} }
fd = VCWD_OPEN_MODE(opened_path, open_flags, 0600); fd = VCWD_OPEN_MODE(opened_path, open_flags, 0600);
@ -170,7 +170,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char **
} else { } else {
*opened_path_p = opened_path; *opened_path_p = opened_path;
} }
free(new_state.cwd); efree(new_state.cwd);
return fd; return fd;
} }
/* }}} */ /* }}} */

View file

@ -1436,7 +1436,7 @@ not_relative_path:
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", cwd, filename, MAXPATHLEN); php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", cwd, filename, MAXPATHLEN);
} }
free(cwd); efree(cwd);
if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(trypath TSRMLS_CC)) { if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(trypath TSRMLS_CC)) {
return NULL; return NULL;