* Inspired by mod_jk's jk_servlet_normalize(). */
| 586 | * Inspired by mod_jk's jk_servlet_normalize(). |
| 587 | */ |
| 588 | static int alias_match_servlet(apr_pool_t *p, |
| 589 | const char **urip, |
| 590 | const char *alias) |
| 591 | { |
| 592 | char *map; |
| 593 | const char *uri = *urip; |
| 594 | apr_array_header_t *stack; |
| 595 | int map_pos, uri_pos, alias_pos, first_pos; |
| 596 | int alias_depth = 0, depth; |
| 597 | |
| 598 | /* Both uri and alias should start with '/' */ |
| 599 | if (uri[0] != '/' || alias[0] != '/') { |
| 600 | return 0; |
| 601 | } |
| 602 | |
| 603 | stack = apr_array_make(p, 5, sizeof(int)); |
| 604 | map = apr_palloc(p, strlen(uri) + 1); |
| 605 | map[0] = '/'; |
| 606 | map[1] = '\0'; |
| 607 | |
| 608 | map_pos = uri_pos = alias_pos = first_pos = 1; |
| 609 | while (uri[uri_pos] != '\0') { |
| 610 | /* Remove path parameters ;foo=bar/ from any path segment */ |
| 611 | if (uri[uri_pos] == ';') { |
| 612 | do { |
| 613 | uri_pos++; |
| 614 | } while (uri[uri_pos] != '/' && uri[uri_pos] != '\0'); |
| 615 | continue; |
| 616 | } |
| 617 | |
| 618 | if (map[map_pos - 1] == '/') { |
| 619 | /* Collapse ///// sequences to / */ |
| 620 | if (uri[uri_pos] == '/') { |
| 621 | do { |
| 622 | uri_pos++; |
| 623 | } while (uri[uri_pos] == '/'); |
| 624 | continue; |
| 625 | } |
| 626 | |
| 627 | if (uri[uri_pos] == '.') { |
| 628 | /* Remove /./ segments */ |
| 629 | if (uri[uri_pos + 1] == '/' |
| 630 | || uri[uri_pos + 1] == ';' |
| 631 | || uri[uri_pos + 1] == '\0') { |
| 632 | uri_pos++; |
| 633 | if (uri[uri_pos] == '/') { |
| 634 | uri_pos++; |
| 635 | } |
| 636 | continue; |
| 637 | } |
| 638 | |
| 639 | /* Remove /xx/../ segments */ |
| 640 | if (uri[uri_pos + 1] == '.' |
| 641 | && (uri[uri_pos + 2] == '/' |
| 642 | || uri[uri_pos + 2] == ';' |
| 643 | || uri[uri_pos + 2] == '\0')) { |
| 644 | /* Wind map segment back the previous one */ |
| 645 | if (map_pos == 1) { |
no outgoing calls
no test coverage detected