예제 #1
0
/* {{{ 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;
}
예제 #2
0
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;
}