@@ -502,7 +502,8 @@ static char x2c(const char *what);
502
AP_DECLARE (int ) ap_normalize_path (char * path , unsigned int flags )
502
AP_DECLARE (int ) ap_normalize_path (char * path , unsigned int flags )
503
{
503
{
504
int ret = 1 ;
504
int ret = 1 ;
505
- apr_size_t l = 1 , w = 1 ;
505
+ apr_size_t l = 1 , w = 1 , n ;
506
+ int decode_unreserved = (flags & AP_NORMALIZE_DECODE_UNRESERVED ) != 0 ;
506
507
507
if (!IS_SLASH (path [0 ])) {
508
if (!IS_SLASH (path [0 ])) {
508
/* Besides "OPTIONS *", a request-target should start with '/'
509
/* Besides "OPTIONS *", a request-target should start with '/'
@@ -529,7 +530,7 @@ AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags)
529
* be decoded to their corresponding unreserved characters by
530
* be decoded to their corresponding unreserved characters by
530
* URI normalizers.
531
* URI normalizers.
531
*/
532
*/
532
- if (( flags & AP_NORMALIZE_DECODE_UNRESERVED )
533
+ if (decode_unreserved
533
&& path [l ] == '%' && apr_isxdigit (path [l + 1 ])
534
&& path [l ] == '%' && apr_isxdigit (path [l + 1 ])
534
&& apr_isxdigit (path [l + 2 ])) {
535
&& apr_isxdigit (path [l + 2 ])) {
535
const char c = x2c (& path [l + 1 ]);
536
const char c = x2c (& path [l + 1 ]);
@@ -567,8 +568,17 @@ AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags)
567
continue ;
568
continue ;
568
}
569
}
569
570
570
- /* Remove /xx/../ segments */
571
+ /* Remove /xx/../ segments (or /xx/.%2e/ when
571
- if (path [l + 1 ] == '.' && IS_SLASH_OR_NUL (path [l + 2 ])) {
572
+ * AP_NORMALIZE_DECODE_UNRESERVED is set since we
573
+ * decoded only the first dot above).
574
+ */
575
+ n = l + 1 ;
576
+ if ((path [n ] == '.' || (decode_unreserved
577
+ && path [n ] == '%'
578
+ && path [++ n ] == '2'
579
+ && (path [++ n ] == 'e'
580
+ || path [n ] == 'E' )))
581
+ && IS_SLASH_OR_NUL (path [n + 1 ])) {
572
/* Wind w back to remove the previous segment */
582
/* Wind w back to remove the previous segment */
573
if (w > 1 ) {
583
if (w > 1 ) {
574
do {
584
do {
@@ -585,7 +595,7 @@ AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags)
585
}
595
}
586
596
587
/* Move l forward to the next segment */
597
/* Move l forward to the next segment */
588
- l += 2 ;
598
+ l = n + 1 ;
589
if (path [l ]) {
599
if (path [l ]) {
590
l ++ ;
600
l ++ ;
591
}
601
}
0 commit comments