www-apache-bugdb mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jaz Brown <jazbr...@mail.com>
Subject mod_rewrite/7879: RewriteRule can erroneously append filename (r->path_info) to URI when it's already there
Date Mon, 18 Jun 2001 15:43:16 GMT

>Number:         7879
>Category:       mod_rewrite
>Synopsis:       RewriteRule can erroneously append filename (r->path_info) to URI when
it's already there
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    apache
>State:          open
>Class:          sw-bug
>Submitter-Id:   apache
>Arrival-Date:   Mon Jun 18 08:50:02 PDT 2001
>Originator:     jazbrown@mail.com
>Release:        1.3.20
Windows 98 SE, Apache 1.3.20 with the bug from PR#7873 taken into account.
In some circumstances, RewriteRule can erroneously add the requested
filename (from path_info) to the end of the requested URI when the filename
is already part of the requested URI. Multiple RewriteRules exacerbate the
problem, adding additional copies of the filename to the end of the URI.
Let us say that you have an account "domain1" on a webhost which gives you
one virtual host (www.domain1.com). This webhost account permits you to
point a second domain (www.domain2.com) to the SAME virtual host (the
webhost is not creating two virtual hosts for you). By default, these two
domains will access the same website. But you wish to emulate a second
virtual host by making www.domain2.com internally redirect to a
subdirectory of www.domain1.com. Thus the webhost's directory structure
might look like this:

/www/domain1/index.html               -- this file is retrieved by http://www.domain1.com/
/www/domain1/domain2/index.html       -- you want to access this with http://www.domain2.com/
/www/domain1/domain2/banana/foo.html  -- a sample web page within a subdirectory of "domain2"

To achieve this, you create the file /www/domain1/.htaccess with the
following content:

    RewriteEngine on
    RewriteBase /
    RewriteCond %{HTTP_HOST} ^www\.domain2\.com$
    RewriteRule ^(.*)$ domain2/$1
    RewriteRule ^(.*)$ $1

This first four lines achieve what you want. The last line represents some
other RewriteRule on your website; the last line given here is just a dummy
RewriteRule that should have no effect (but in fact does, and that is the
bug I am demonstrating).

Now, you try to access http://www.domain2.com/banana/foo.html
The request fails, and Apache generates an error. RewriteLog with
RewriteLogLevel 9 gives the following 10 lines:

(3) [per-dir /www/domain1/] add path-info postfix: /www/domain1/banana -> /www/domain1/banana/foo.html
(3) [per-dir /www/domain1/] strip per-dir prefix: /www/domain1/banana/foo.html -> banana/foo.html
(3) [per-dir /www/domain1/] applying pattern '^(.*)$' to uri 'banana/foo.html'
(2) [per-dir /www/domain1/] rewrite banana/foo.html -> domain2/banana/foo.html
(3) [per-dir /www/domain1/] add per-dir prefix: domain2/banana/foo.html -> /www/domain1/domain2/banana/foo.html
(3) [per-dir /www/domain1/] add path-info postfix: /www/domain1/domain2/banana/foo.html ->
(3) [per-dir /www/domain1/] strip per-dir prefix: /www/domain1/domain2/banana/foo.html/foo.html
-> domain2/banana/foo.html/foo.html
(3) [per-dir /www/domain1/] applying pattern '^(.*)$' to uri 'domain2/banana/foo.html/foo.html'
(2) [per-dir /www/domain1/] rewrite domain2/banana/foo.html/foo.html -> domain2/banana/foo.html/foo.html
(3) [per-dir /www/domain1/] add per-dir prefix: domain2/banana/foo.html/foo.html -> /www/domain1/domain2/banana/foo.html/foo.html

The first five lines are the result of the first RewriteRule, which works
correctly. It begins by adding the path-info postfix, which is needed to
generate a full URI to work on. It ends up by correctly generating the path

The second five lines are the result of the second RewriteRule. Note that
the first thing that is done is that the path-info postfix is added
_again_, despite that the working URI already has the filename, and hence
the filename gets erroneously added to the URI a second time.

If there were more RewriteRules, they could each add the filename again,
making the problem worse and worse.
mod_rewrite.c needs to be modified to prevent a series of RewriteRules
appending r->path_info to r->filename more than once. r->path_info gets
added to the variable 'uri' in the function apply_rewrite_rule() on line
1782 of mod_rewrite.c:
        uri = ap_pstrcat(r->pool, uri, r->path_info, NULL);
and this gets committed to r->filename on line 1977:
    r->filename = ap_pstrdup(r->pool, newuri);
One simple solution to fix this problem would be to zero out r->path_info
after line 1782 with something like:
        r->path_info[0] = '\0';
however this may not be desirable if the value of r->path_info is needed at
some other time (I don't know whether it is or might be).

Perhaps a better solution might be if the apply_rewrite_rule() function
kept track of whether r->path_info gets appended to the URI on line 1782.
If this change gets committed to r->filename on line 1977, then when the
function returns back to apply_rewrite_list(), it could somehow signal to
apply_rewrite_list() whether r->path_info got appended to

When apply_rewrite_list() calls apply_rewrite_rule() to process
subsequent RewriteRules, it would then in turn pass some parameter
indicating whether r->path_info has already been appended to r->filename.
The test on line 1779 should include a check on this parameter, and thus the
test evaluates to FALSE if r->file_path has been appended to r->filename by a
previous call to apply_rewrite_rule().
 [In order for any reply to be added to the PR database, you need]
 [to include <apbugs@Apache.Org> in the Cc line and make sure the]
 [subject line starts with the report component and number, with ]
 [or without any 'Re:' prefixes (such as "general/1098:" or      ]
 ["Re: general/1098:").  If the subject doesn't match this       ]
 [pattern, your message will be misfiled and ignored.  The       ]
 ["apbugs" address is not added to the Cc line of messages from  ]
 [the database automatically because of the potential for mail   ]
 [loops.  If you do not include this Cc, your reply may be ig-   ]
 [nored unless you are responding to an explicit request from a  ]
 [developer.  Reply only with text; DO NOT SEND ATTACHMENTS!     ]

View raw message