dmitry Wed Sep 20 07:35:59 2006 UTC Added files: (Branch: PHP_5_2) /php-src/tests/lang bug38579.inc bug38579.phpt
Modified files: /php-src NEWS /TSRM tsrm_virtual_cwd.c Log: Fixed bug #38579 (include_once() may include the same file twice)
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.259&r2=1.2027.2.547.2.260&diff_format=u Index: php-src/NEWS diff -u php-src/NEWS:1.2027.2.547.2.259 php-src/NEWS:1.2027.2.547.2.260 --- php-src/NEWS:1.2027.2.547.2.259 Tue Sep 19 21:36:53 2006 +++ php-src/NEWS Wed Sep 20 07:35:58 2006 @@ -8,6 +8,7 @@ (Tony) - Fixed bug #38623 (leaks in a tricky code with switch() and exceptions). (Dmitry) +- Fixed bug #38579 (include_once() may include the same file twice). (Dmitry) - Fixed bug #38574 (missing curl constants and improper constant detection). (Ilia) - Fixed bug #37870 (pgo_pgsql tries to de-allocate unused statements). http://cvs.php.net/viewvc.cgi/TSRM/tsrm_virtual_cwd.c?r1=1.74.2.9.2.3&r2=1.74.2.9.2.4&diff_format=u Index: TSRM/tsrm_virtual_cwd.c diff -u TSRM/tsrm_virtual_cwd.c:1.74.2.9.2.3 TSRM/tsrm_virtual_cwd.c:1.74.2.9.2.4 --- TSRM/tsrm_virtual_cwd.c:1.74.2.9.2.3 Sat Aug 5 13:17:50 2006 +++ TSRM/tsrm_virtual_cwd.c Wed Sep 20 07:35:58 2006 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_virtual_cwd.c,v 1.74.2.9.2.3 2006/08/05 13:17:50 tony2001 Exp $ */ +/* $Id: tsrm_virtual_cwd.c,v 1.74.2.9.2.4 2006/09/20 07:35:58 dmitry Exp $ */ #include <sys/types.h> #include <sys/stat.h> @@ -366,23 +366,11 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath) { int path_length = strlen(path); - char *ptr, *path_copy; - char *tok = NULL; - int ptr_length; cwd_state old_state; - int ret = 0; - int copy_amount = -1; - char *free_path; - unsigned char is_absolute = 0; -#ifndef TSRM_WIN32 - char resolved_path[MAXPATHLEN]; -#else - char *new_path; -#endif char orig_path[MAXPATHLEN]; - int orig_path_len = 0; realpath_cache_bucket *bucket; time_t t = 0; + int ret; TSRMLS_FETCH(); if (path_length == 0) @@ -390,21 +378,29 @@ if (path_length >= MAXPATHLEN) return (1); - if (use_realpath && CWDG(realpath_cache_size_limit)) { - if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) { - memcpy(orig_path, path, path_length+1); - orig_path_len = path_length; - } else { - orig_path_len = path_length + state->cwd_length + 1; - if (orig_path_len >= MAXPATHLEN) { - return 1; - } - memcpy(orig_path, state->cwd, state->cwd_length); - orig_path[state->cwd_length] = DEFAULT_SLASH; - memcpy(orig_path + state->cwd_length + 1, path, path_length + 1); +#if VIRTUAL_CWD_DEBUG + fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path); +#endif + + /* 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)) { + int orig_path_len = path_length + state->cwd_length + 1; + + if (orig_path_len >= MAXPATHLEN) { + return 1; } + memcpy(orig_path, state->cwd, state->cwd_length); + orig_path[state->cwd_length] = DEFAULT_SLASH; + memcpy(orig_path + state->cwd_length + 1, path, path_length + 1); + path = orig_path; + path_length = orig_path_len; + } + + if (use_realpath && CWDG(realpath_cache_size_limit)) { t = CWDG(realpath_cache_ttl)?time(NULL):0; - if ((bucket = realpath_cache_find(orig_path, orig_path_len, t TSRMLS_CC)) != NULL) { + if ((bucket = realpath_cache_find(path, path_length, t TSRMLS_CC)) != NULL) { int len = bucket->realpath_len; CWD_STATE_COPY(&old_state, state); @@ -421,107 +417,55 @@ } } } + + if (use_realpath) { #if !defined(TSRM_WIN32) && !defined(NETWARE) - /* 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) { - if (realpath(path, resolved_path)) { /* Note: Not threadsafe on older *BSD's */ - path = resolved_path; - path_length = strlen(path); - } else { - /* disable for now - return 1; */ - } - } - } else { /* Concat current directory with relative path and then run realpath() on it */ - char *tmp; - char *ptr; + char resolved_path[MAXPATHLEN]; - ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); - if (!tmp) { - return 1; - } - memcpy(ptr, state->cwd, state->cwd_length); - ptr += state->cwd_length; - *ptr++ = DEFAULT_SLASH; - memcpy(ptr, path, path_length); - ptr += path_length; - *ptr = '\0'; - if (strlen(tmp) >= MAXPATHLEN) { - free(tmp); - return 1; - } - if (use_realpath) { - if (realpath(tmp, resolved_path)) { - path = resolved_path; - path_length = strlen(path); - } else { - /* disable for now - free(tmp); - return 1; */ - } - } - free(tmp); - } -#endif -#if defined(TSRM_WIN32) - { - int new_path_length; - - new_path_length = GetLongPathName(path, NULL, 0); - if (new_path_length == 0) { - goto php_failed_getlongpath; + if (!realpath(path, resolved_path)) { /* Note: Not threadsafe on older *BSD's */ + goto no_realpath; } + CWD_STATE_COPY(&old_state, state); - /* GetLongPathName already counts the \0 */ - new_path = (char *) malloc(new_path_length); - if (!new_path) { - return 1; - } - - if (GetLongPathName(path, new_path, new_path_length) != 0) { - path = new_path; - path_length = new_path_length; - } else { - free(new_path); -php_failed_getlongpath: - new_path = NULL; - } - } + state->cwd_length = strlen(resolved_path); + state->cwd = (char *) realloc(state->cwd, state->cwd_length+1); + memcpy(state->cwd, resolved_path, state->cwd_length+1); +#else + goto no_realpath; #endif - free_path = path_copy = tsrm_strndup(path, path_length); - - CWD_STATE_COPY(&old_state, state); -#if VIRTUAL_CWD_DEBUG - fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path); + } else { + char *ptr, *path_copy, *free_path; + char *tok = NULL; + int ptr_length; + +no_realpath: + + free_path = path_copy = tsrm_strndup(path, path_length); + CWD_STATE_COPY(&old_state, state); + +#ifdef TSRM_WIN32 + if (path_length >= 2 && path[1] == ':') { + state->cwd = (char *) realloc(state->cwd, 2 + 1); + state->cwd[0] = toupper(path[0]); + state->cwd[1] = ':'; + state->cwd[2] = '\0'; + state->cwd_length = 2; + path_copy += 2; + } else if (IS_UNC_PATH(path, path_length)) { + state->cwd = (char *) realloc(state->cwd, 1 + 1); + state->cwd[0] = DEFAULT_SLASH; + state->cwd[1] = '\0'; + state->cwd_length = 1; + path_copy += 2; + } else { #endif - if (IS_ABSOLUTE_PATH(path_copy, path_length)) { - copy_amount = COPY_WHEN_ABSOLUTE(path_copy); - is_absolute = 1; + state->cwd = (char *) realloc(state->cwd, 1); + state->cwd[0] = '\0'; + state->cwd_length = 0; #ifdef TSRM_WIN32 - } else if (IS_SLASH(path_copy[0])) { - copy_amount = 2; -#endif - } - - if (copy_amount != -1) { - state->cwd = (char *) realloc(state->cwd, copy_amount + 1); - if (copy_amount) { - if (is_absolute) { - memcpy(state->cwd, path_copy, copy_amount); - path_copy += copy_amount; - } else { - memcpy(state->cwd, old_state.cwd, copy_amount); - } } - state->cwd[copy_amount] = '\0'; - state->cwd_length = copy_amount; - } - - - if (state->cwd_length > 0 || IS_ABSOLUTE_PATH(path, path_length)) { +#endif + ptr = tsrm_strtok_r(path_copy, TOKENIZER_STRING, &tok); while (ptr) { ptr_length = strlen(ptr); @@ -551,7 +495,8 @@ 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]!='/') || + if (state->cwd_length < 2 || + (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; } @@ -575,32 +520,42 @@ state->cwd[state->cwd_length++] = DEFAULT_SLASH; #endif memcpy(&state->cwd[state->cwd_length], ptr, ptr_length+1); + +#ifdef TSRM_WIN32 + if (use_realpath) { + WIN32_FIND_DATA data; + HANDLE hFind; + + if ((hFind = FindFirstFile(state->cwd, &data)) != INVALID_HANDLE_VALUE) { + int length = strlen(data.cFileName); + + if (length != ptr_length) { + state->cwd = (char *) realloc(state->cwd, state->cwd_length+length+1); + } + memcpy(&state->cwd[state->cwd_length], data.cFileName, length+1); + ptr_length = length; + FindClose(hFind); + } + } +#endif + state->cwd_length += ptr_length; } ptr = tsrm_strtok_r(NULL, TOKENIZER_STRING, &tok); } + free(free_path); + 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; } -#ifdef TSRM_WIN32 - if (new_path) { - free(new_path); - } -#endif - free(free_path); - if (use_realpath && CWDG(realpath_cache_size_limit)) { - realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC); + realpath_cache_add(path, path_length, state->cwd, state->cwd_length, t TSRMLS_CC); } if (verify_path && verify_path(state)) { http://cvs.php.net/viewvc.cgi/php-src/tests/lang/bug38579.inc?view=markup&rev=1.1 Index: php-src/tests/lang/bug38579.inc +++ php-src/tests/lang/bug38579.inc http://cvs.php.net/viewvc.cgi/php-src/tests/lang/bug38579.phpt?view=markup&rev=1.1 Index: php-src/tests/lang/bug38579.phpt +++ php-src/tests/lang/bug38579.phpt
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php