/* {{{ expand_filepath_use_realpath */ PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int realpath_mode) { cwd_state new_state; char cwd[MAXPATHLEN]; int copy_len; int path_len; if (!filepath[0]) { return NULL; } path_len = (int)strlen(filepath); if (IS_ABSOLUTE_PATH(filepath, path_len)) { cwd[0] = '\0'; } else { const char *iam = SG(request_info).path_translated; const char *result; if (relative_to) { if (relative_to_len > MAXPATHLEN-1U) { return NULL; } result = relative_to; memcpy(cwd, relative_to, relative_to_len+1U); } else { result = VCWD_GETCWD(cwd, MAXPATHLEN); } if (!result && (iam != filepath)) { int fdtest = -1; fdtest = VCWD_OPEN(filepath, O_RDONLY); if (fdtest != -1) { /* return a relative file path if for any reason * we cannot cannot getcwd() and the requested, * relatively referenced file is accessible */ copy_len = path_len > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : path_len; if (real_path) { memcpy(real_path, filepath, copy_len); real_path[copy_len] = '\0'; } else { real_path = estrndup(filepath, copy_len); } close(fdtest); return real_path; } else { cwd[0] = '\0'; } } else if (!result) { cwd[0] = '\0'; } } new_state.cwd = estrdup(cwd); new_state.cwd_length = (int)strlen(cwd); if (virtual_file_ex(&new_state, filepath, NULL, realpath_mode)) { efree(new_state.cwd); return NULL; } if (real_path) { copy_len = new_state.cwd_length > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : new_state.cwd_length; memcpy(real_path, new_state.cwd, copy_len); real_path[copy_len] = '\0'; } else { real_path = estrndup(new_state.cwd, new_state.cwd_length); } efree(new_state.cwd); return real_path; }
static int php_do_open_temporary_file(const char *path, const char *pfx, zend_string **opened_path_p) { char *trailing_slash; #ifdef PHP_WIN32 char *opened_path = NULL; size_t opened_path_len; wchar_t *cwdw, *pfxw, pathw[MAXPATHLEN]; #else char opened_path[MAXPATHLEN]; #endif char cwd[MAXPATHLEN]; cwd_state new_state; int fd = -1; #ifndef HAVE_MKSTEMP int open_flags = O_CREAT | O_TRUNC | O_RDWR #ifdef PHP_WIN32 | _O_BINARY #endif ; #endif if (!path || !path[0]) { return -1; } #ifdef PHP_WIN32 if (!php_win32_check_trailing_space(pfx, (const int)strlen(pfx))) { SetLastError(ERROR_INVALID_NAME); return -1; } #endif if (!VCWD_GETCWD(cwd, MAXPATHLEN)) { cwd[0] = '\0'; } new_state.cwd = estrdup(cwd); new_state.cwd_length = (int)strlen(cwd); if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) { efree(new_state.cwd); return -1; } if (IS_SLASH(new_state.cwd[new_state.cwd_length - 1])) { trailing_slash = ""; } else { trailing_slash = "/"; } #ifndef PHP_WIN32 if (snprintf(opened_path, MAXPATHLEN, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) >= MAXPATHLEN) { efree(new_state.cwd); return -1; } #endif #ifdef PHP_WIN32 cwdw = php_win32_ioutil_any_to_w(new_state.cwd); pfxw = php_win32_ioutil_any_to_w(pfx); if (!cwdw || !pfxw) { free(cwdw); free(pfxw); efree(new_state.cwd); return -1; } if (GetTempFileNameW(cwdw, pfxw, 0, pathw)) { opened_path = php_win32_ioutil_conv_w_to_any(pathw, PHP_WIN32_CP_IGNORE_LEN, &opened_path_len); if (!opened_path || opened_path_len >= MAXPATHLEN) { free(cwdw); free(pfxw); efree(new_state.cwd); return -1; } assert(strlen(opened_path) == opened_path_len); /* Some versions of windows set the temp file to be read-only, * which means that opening it will fail... */ if (VCWD_CHMOD(opened_path, 0600)) { free(cwdw); free(pfxw); efree(new_state.cwd); free(opened_path); return -1; } fd = VCWD_OPEN_MODE(opened_path, open_flags, 0600); } free(cwdw); free(pfxw); #elif defined(HAVE_MKSTEMP) fd = mkstemp(opened_path); #else if (mktemp(opened_path)) { fd = VCWD_OPEN(opened_path, open_flags); } #endif #ifdef PHP_WIN32 if (fd != -1 && opened_path_p) { *opened_path_p = zend_string_init(opened_path, opened_path_len, 0); } free(opened_path); #else if (fd != -1 && opened_path_p) { *opened_path_p = zend_string_init(opened_path, strlen(opened_path), 0); } #endif efree(new_state.cwd); return fd; }