From: André Malo Date: Wed, 2 Apr 2003 21:01:09 +0000 (+0000) Subject: Fix the prefix_stat function. (which does a stat call on the first X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=221e35e344b2ab4cbe481fa8cf48c27435fde80c;p=thirdparty%2Fapache%2Fhttpd.git Fix the prefix_stat function. (which does a stat call on the first path segment). This function was still tailored for unix systems only. It should work on other systems as well now. Note that in 2.x we use the apr_filepath_root function that doesn't exist in 1.3. It is replaced by some simple workaround stuff which behaves similar. Obtained from: 2.1 (r1.143) Reviewed by: Brad Nicholes, Will Rowe git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x@99178 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/modules/standard/mod_rewrite.c b/src/modules/standard/mod_rewrite.c index 02e0011fa7b..fff2e6ea3b1 100644 --- a/src/modules/standard/mod_rewrite.c +++ b/src/modules/standard/mod_rewrite.c @@ -1039,7 +1039,6 @@ static int hook_uri2file(request_rec *r) char docroot[512]; char *cp, *cp2; const char *ccp; - struct stat finfo; unsigned int port; int rulestatus; int n; @@ -1271,7 +1270,7 @@ static int hook_uri2file(request_rec *r) * because we only do stat() on the first directory * and this gets cached by the kernel for along time! */ - n = prefix_stat(r->filename, &finfo); + n = prefix_stat(r->filename, r->pool); if (n == 0) { if ((ccp = ap_document_root(r)) != NULL) { l = ap_cpystrn(docroot, ccp, sizeof(docroot)) - docroot; @@ -4164,24 +4163,68 @@ static int subreq_ok(request_rec *r) ** */ -static int prefix_stat(const char *path, struct stat *sb) +static int prefix_stat(const char *path, ap_pool *pool) { - char curpath[LONG_STRING_LEN]; - char *cp; + const char *curpath = path; + char *root; + char *slash; + char *statpath; + struct stat sb; - ap_cpystrn(curpath, path, sizeof(curpath)); - if (curpath[0] != '/') { + if (!ap_os_is_path_absolute(curpath)) { return 0; } - if ((cp = strchr(curpath+1, '/')) != NULL) { - *cp = '\0'; + + /* need to be a bit tricky here. + * Actually we're looking for the first path segment ... + */ + if (*curpath != '/') { + /* be safe: +1 = '\0'; +1 = possible additional '\0' + * from ap_make_dirstr_prefix + */ + root = ap_palloc(pool, strlen(curpath) + 2); + slash = ap_make_dirstr_prefix(root, curpath, 1); + curpath += strlen(root); } - if (stat(curpath, sb) == 0) { - return 1; + else { +#if defined(HAVE_UNC_PATHS) + /* Check for UNC names. */ + if (curpath[1] == '/') { + slash = strchr(curpath + 2, '/'); + + /* XXX not sure here. Be safe for now */ + if (!slash) { + return 0; + } + root = ap_pstrndup(pool, curpath, slash - curpath + 1); + curpath += strlen(root); + } + else { +#endif /* UNC */ + root = "/"; + ++curpath; +#if defined(HAVE_UNC_PATHS) + } +#endif + } + + /* let's recognize slashes only, the mod_rewrite semantics are opaque + * enough. + */ + if ((slash = strchr(curpath, '/')) != NULL) { + statpath = ap_pstrcat(pool, root, + ap_pstrndup(pool, curpath, slash - curpath), + NULL); } else { - return 0; + statpath = ap_pstrcat(pool, root, curpath, NULL); } + + if (stat(statpath, &sb) == 0) { + return 1; + } + + return 0; } diff --git a/src/modules/standard/mod_rewrite.h b/src/modules/standard/mod_rewrite.h index 47f43917f5a..942461ec195 100644 --- a/src/modules/standard/mod_rewrite.h +++ b/src/modules/standard/mod_rewrite.h @@ -496,7 +496,7 @@ static void store_cache_string(cache *c, char *res, cacheentry *ce); static char *subst_prefix_path(request_rec *r, char *input, char *match, char *subst); static int parseargline(char *str, char **a1, char **a2, char **a3); -static int prefix_stat(const char *path, struct stat *sb); +static int prefix_stat(const char *path, ap_pool *pool); static void add_env_variable(request_rec *r, char *s); static int subreq_ok(request_rec *r); static int is_redirect_limit_exceeded(request_rec *r);