* Escapes a backreference in a similar way as php's urlencode does. * Based on ap_os_escape_path in server/util.c */
| 727 | * Based on ap_os_escape_path in server/util.c |
| 728 | */ |
| 729 | static char *escape_backref(apr_pool_t *p, const char *path, |
| 730 | const char *escapeme, const char *noescapeme, |
| 731 | int flags) |
| 732 | { |
| 733 | char *copy = apr_palloc(p, 3 * strlen(path) + 1); |
| 734 | const unsigned char *s = (const unsigned char *)path; |
| 735 | unsigned char *d = (unsigned char *)copy; |
| 736 | int noplus = (flags & RULEFLAG_ESCAPENOPLUS) != 0; |
| 737 | int ctls = (flags & RULEFLAG_ESCAPECTLS) != 0; |
| 738 | unsigned char c; |
| 739 | |
| 740 | while ((c = *s)) { |
| 741 | if (((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme) |
| 742 | || (escapeme && ap_strchr_c(escapeme, c))) |
| 743 | && (!noescapeme || !ap_strchr_c(noescapeme, c))) { |
| 744 | if (apr_isalnum(c) || c == '_') { |
| 745 | *d++ = c; |
| 746 | } |
| 747 | else if (c == ' ' && !noplus) { |
| 748 | *d++ = '+'; |
| 749 | } |
| 750 | else { |
| 751 | d = c2x(c, '%', d); |
| 752 | } |
| 753 | } |
| 754 | else { |
| 755 | *d++ = c; |
| 756 | } |
| 757 | ++s; |
| 758 | } |
| 759 | *d = '\0'; |
| 760 | return copy; |
| 761 | } |
| 762 | |
| 763 | /* |
| 764 | * escape absolute uri, which may or may not be path oriented. |
no test coverage detected