On 1/17/22 5:10 PM, minf...@apache.org wrote:
> Author: minfrin
> Date: Mon Jan 17 16:10:51 2022
> New Revision: 1897156
>
> URL: http://svn.apache.org/viewvc?rev=1897156&view=rev
> Log:
> core: Allow an optional expression to be specified for an effective
> path in the DirectoryMatch and LocationMatch directives. This allows
> modules like mod_dav to map URLs to URL spaces or to directories on
> the filesystem.
>
> Modified:
> httpd/httpd/trunk/CHANGES
> httpd/httpd/trunk/docs/log-message-tags/next-number
> httpd/httpd/trunk/docs/manual/mod/core.xml
> httpd/httpd/trunk/modules/dav/main/mod_dav.c
> httpd/httpd/trunk/server/core.c
>
avior in the filesystem
>
> Modified: httpd/httpd/trunk/modules/dav/main/mod_dav.c
> URL:
> http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/dav/main/mod_dav.c?rev=1897156&r1=1897155&r2=1897156&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/dav/main/mod_dav.c (original)
> +++ httpd/httpd/trunk/modules/dav/main/mod_dav.c Mon Jan 17 16:10:51 2022
>
> @@ -723,6 +737,57 @@ static int dav_get_overwrite(request_rec
> return -1;
> }
>
> +static int uripath_is_canonical(const char *uripath)
Isn't this a filesystem path we are talking about in the <Directory > case?
How does this function work on Windows when people might use '\' instead of '/'?
> +{
> + const char *dot_pos, *ptr = uripath;
> + apr_size_t i, len;
> + unsigned pattern = 0;
> +
> + /* URIPATH is canonical if it has:
> + * - no '.' segments
> + * - no closing '/'
> + * - no '//'
> + */
> +
> + if (ptr[0] == '.'
> + && (ptr[1] == '/' || ptr[1] == '\0'
> + || (ptr[1] == '.' && (ptr[2] == '/' || ptr[2] ==
> '\0')))) {
> + return 0;
> + }
> +
> + /* valid special cases */
> + len = strlen(ptr);
> + if (len < 2) {
Empty pathes ("") are ok?
> + return 1;
> + }
> +
> + /* invalid endings */
> + if (ptr[len - 1] == '/' || (ptr[len - 1] == '.' && ptr[len - 2] == '/'))
> {
> + return 0;
> + }
> +
> + /* '.' are rare. So, search for them globally. There will often be no
> + * more than one hit. Also note that we already checked for invalid
> + * starts and endings, i.e. we only need to check for "/./"
Why don't we need to look for /../ segments?
> + */
> + for (dot_pos = memchr(ptr, '.', len); dot_pos;
> + dot_pos = strchr(dot_pos + 1, '.')) {
> + if (dot_pos > ptr && dot_pos[-1] == '/' && dot_pos[1] == '/') {
> + return 0;
> + }
> + }
> +
> + /* Now validate the rest of the path. */
> + for (i = 0; i < len - 1; ++i) {
> + pattern = ((pattern & 0xff) << 8) + (unsigned char) ptr[i];
> + if (pattern == 0x101 * (unsigned char) ('/')) {
> + return 0;
> + }
> + }
> +
> + return 1;
> +}
> +
> /* resolve a request URI to a resource descriptor.
> *
> * If label_allowed != 0, then allow the request target to be altered by