https://issues.apache.org/bugzilla/show_bug.cgi?id=44922

           Summary: RewriteRules in .htaccess erroneously inject PATH_INFO
           Product: Apache httpd-2
           Version: 2.2.8
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: mod_rewrite
        AssignedTo: bugs@httpd.apache.org
        ReportedBy: [EMAIL PROTECTED]


Created an attachment (id=21906)
 --> (https://issues.apache.org/bugzilla/attachment.cgi?id=21906)
RewriteLog

The problem, superficially:

If multiple RewriteRules within a .htaccess file match, extra copies of
PATH_INFO may accumulate at the end of the URI (depending on whether or not the
substitutions include appropriate backreferences to the matched string).

Because there are many configurations that will be somehow affected by this
problem, there is no simple cause and effect. I have provided one example
below.


In more depth:

This is my best guess from looking at the mod_rewrite source.

When using mod_rewrite in a per-directory context, r->path_info is appended to
ctx->uri prior to *each* RewriteRule. If a RewriteRule does not match, this is
discarded and has no effect. If a RewriteRule does match, however, the entire
substitution is incorporated into r->filename.

This means that subsequent rules will get a "tailgating" copy of PATH_INFO. If
more rules match then this can get worse.

Now, each matching rule will either include (and possibly modify) the PATH_INFO
portion in the substituion, or will leave it out - in either case it doesn't
make sense for further rules to have it re-appended.

This is the code that does the appending:

        if (r->path_info && *r->path_info) {
            rewritelog((r, 3, ctx->perdir, "add path info postfix: %s -> %s%s",
                        ctx->uri, ctx->uri, r->path_info));
            ctx->uri = apr_pstrcat(r->pool, ctx->uri, r->path_info, NULL);
        }

(This agrees with the RewriteLog)


Tested on:

Linux (multiple boxes); Apache versions 2.2.8, 2.2.3, 2.0.61

I think this problem has been reported before (see
http://archive.apache.org/gnats/7879 which claims it was fixed in 2.0.30... but
it's still happening)


Example:

Here's an example of an affected configuration. This comes from a .htaccess
file placed in DocumentRoot. It is supposed to replace all underscores in a URI
with hyphens.

RewriteEngine On
RewriteBase /
RewriteRule ^(.*)_(.*)$ $1-$2 [N]

Make a request for "/_f_o_o_" and it will be correctly rewritten to "/-f-o-o-".
(That's because PATH_INFO is empty.)

Make a request for "/_f_o_o_/bar" and it will be rewritten to
"/-f-o-o-/bar/bar/bar/bar". (That is, unless you happen to have a _f_o_o_
directory, in which case PATH_INFO will be empty and the rewriting will work as
desired.)

Note that there are five underscores but only four copies of PATH_INFO - this
is because the first time the rule matches, appending PATH_INFO is correct
behaviour because r->filename does not include it.

Make a request for "/foo/b_ar" and an infinite loop will ensue, since every
time an underscore is replaced, a new one will be appended prior to the next
rule.

See the attached RewriteLog, which contains rewrite information for the first
two requests.

As I have said, there are many ways to be affected by this problem - the above
method may have a simple workaround, but there will be more complex cases where
workarounds are difficult.


Thoughts on solution:

Once a substitution is made, PATH_INFO is essentially rendered invalid: it will
contain something not consistent with the URI. It would be quite easy to set
r->path_info to an empty string if any rule matched, and that should solve the
problem. Otherwise, a flag could be added (to rewrite_ctx perhaps) indicating
whether or not any rules have matched yet.


-- 
Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to