| 946 | } |
| 947 | |
| 948 | static apr_status_t uri_check(apr_uri_t *uri_parsed, apr_pool_t *p, |
| 949 | const char *uri, const char **perr) |
| 950 | { |
| 951 | const char *s, *err = NULL; |
| 952 | apr_status_t rv; |
| 953 | |
| 954 | if (APR_SUCCESS != (rv = apr_uri_parse(p, uri, uri_parsed))) { |
| 955 | err = "not an uri"; |
| 956 | } |
| 957 | else if (uri_parsed->scheme) { |
| 958 | if (strlen(uri_parsed->scheme) + 1 >= strlen(uri)) { |
| 959 | err = "missing uri identifier"; |
| 960 | } |
| 961 | else if (!strncmp("http", uri_parsed->scheme, 4)) { |
| 962 | if (!uri_parsed->hostname) { |
| 963 | err = "missing hostname"; |
| 964 | } |
| 965 | else if (!md_dns_is_name(p, uri_parsed->hostname, 0)) { |
| 966 | err = "invalid hostname"; |
| 967 | } |
| 968 | if (uri_parsed->port_str |
| 969 | && (!apr_isdigit(uri_parsed->port_str[0]) |
| 970 | || uri_parsed->port == 0 |
| 971 | || uri_parsed->port > 65353)) { |
| 972 | err = "invalid port"; |
| 973 | } |
| 974 | } |
| 975 | else if (!strcmp("mailto", uri_parsed->scheme)) { |
| 976 | s = strchr(uri, '@'); |
| 977 | if (!s) { |
| 978 | err = "missing @"; |
| 979 | } |
| 980 | else if (strchr(s+1, '@')) { |
| 981 | err = "duplicate @"; |
| 982 | } |
| 983 | else if (s == uri + strlen(uri_parsed->scheme) + 1) { |
| 984 | err = "missing local part"; |
| 985 | } |
| 986 | else if (s == (uri + strlen(uri)-1)) { |
| 987 | err = "missing hostname"; |
| 988 | } |
| 989 | else if (strstr(uri, "..")) { |
| 990 | err = "double period"; |
| 991 | } |
| 992 | } |
| 993 | } |
| 994 | if (strchr(uri, ' ') || strchr(uri, '\t') ) { |
| 995 | err = "whitespace in uri"; |
| 996 | } |
| 997 | |
| 998 | if (err) { |
| 999 | rv = APR_EINVAL; |
| 1000 | } |
| 1001 | *perr = err; |
| 1002 | return rv; |
| 1003 | } |
| 1004 | |
| 1005 | apr_status_t md_util_abs_uri_check(apr_pool_t *p, const char *uri, const char **perr) |
no test coverage detected