* stat() only the first segment of a path, and only if it matches the output of the last matching rule */
| 1002 | * stat() only the first segment of a path, and only if it matches the output of the last matching rule |
| 1003 | */ |
| 1004 | static int prefix_stat(request_rec *r, const char *path, apr_pool_t *pool, rewriterule_entry *lastsub) |
| 1005 | { |
| 1006 | const char *curpath = path; |
| 1007 | const char *root; |
| 1008 | const char *slash; |
| 1009 | char *statpath; |
| 1010 | apr_status_t rv; |
| 1011 | |
| 1012 | rv = apr_filepath_root(&root, &curpath, APR_FILEPATH_TRUENAME, pool); |
| 1013 | |
| 1014 | if (rv != APR_SUCCESS) { |
| 1015 | return 0; |
| 1016 | } |
| 1017 | |
| 1018 | /* let's recognize slashes only, the mod_rewrite semantics are opaque |
| 1019 | * enough. |
| 1020 | */ |
| 1021 | if ((slash = ap_strchr_c(curpath, '/')) != NULL) { |
| 1022 | rv = apr_filepath_merge(&statpath, root, |
| 1023 | apr_pstrndup(pool, curpath, |
| 1024 | (apr_size_t)(slash - curpath)), |
| 1025 | APR_FILEPATH_NOTABOVEROOT | |
| 1026 | APR_FILEPATH_NOTRELATIVE, pool); |
| 1027 | } |
| 1028 | else { |
| 1029 | rv = apr_filepath_merge(&statpath, root, curpath, |
| 1030 | APR_FILEPATH_NOTABOVEROOT | |
| 1031 | APR_FILEPATH_NOTRELATIVE, pool); |
| 1032 | } |
| 1033 | |
| 1034 | if (rv == APR_SUCCESS) { |
| 1035 | apr_finfo_t sb; |
| 1036 | |
| 1037 | if (apr_stat(&sb, statpath, APR_FINFO_MIN, pool) == APR_SUCCESS) { |
| 1038 | if (!lastsub) { |
| 1039 | rewritelog(r, 3, NULL, "prefix_stat no lastsub subst prefix %s", statpath); |
| 1040 | return 1; |
| 1041 | } |
| 1042 | |
| 1043 | rewritelog(r, 3, NULL, "prefix_stat compare statpath %s and lastsub output %s STATOK %d ", |
| 1044 | statpath, lastsub->output, lastsub->flags & RULEFLAG_UNSAFE_PREFIX_STAT); |
| 1045 | if (lastsub->flags & RULEFLAG_UNSAFE_PREFIX_STAT) { |
| 1046 | return 1; |
| 1047 | } |
| 1048 | else { |
| 1049 | const char *docroot = ap_document_root(r); |
| 1050 | const char *context_docroot = ap_context_document_root(r); |
| 1051 | /* |
| 1052 | * As an example, path (r->filename) is /var/foo/bar/baz.html |
| 1053 | * even if the flag is not set, we can accept a rule that |
| 1054 | * began with a literal /var (stapath), or if the entire path |
| 1055 | * starts with the docroot or context document root |
| 1056 | */ |
| 1057 | if (startsWith(r, lastsub->output, statpath) || |
| 1058 | startsWith(r, path, docroot) || |
| 1059 | ((docroot != context_docroot) && |
| 1060 | startsWith(r, path, context_docroot))) { |
| 1061 | return 1; |
no test coverage detected