3 require_once 'HTMLPurifier/URI.php';
6 * Parses a URI into the components and fragment identifier as specified
8 * @todo Replace regexps with a native PHP parser
10 class HTMLPurifier_URIParser
15 * @param $uri string URI to parse
16 * @return HTMLPurifier_URI representation of URI
18 function parse($uri) {
20 '(([^:/?#<>\'"]+):)?'. // 2. Scheme
21 '(//([^/?#<>\'"]*))?'. // 4. Authority
22 '([^?#<>\'"]*)'. // 5. Path
23 '(\?([^#<>\'"]*))?'. // 7. Query
24 '(#([^<>\'"]*))?'. // 8. Fragment
28 $result = preg_match($r_URI, $uri, $matches);
30 if (!$result) return false; // *really* invalid URI
33 $scheme = !empty($matches[1]) ?
$matches[2] : null;
34 $authority = !empty($matches[3]) ?
$matches[4] : null;
35 $path = $matches[5]; // always present, can be empty
36 $query = !empty($matches[6]) ?
$matches[7] : null;
37 $fragment = !empty($matches[8]) ?
$matches[9] : null;
39 // further parse authority
40 if ($authority !== null) {
41 // ridiculously inefficient: it's a stacked regex!
42 $HEXDIG = '[A-Fa-f0-9]';
43 $unreserved = 'A-Za-z0-9-._~'; // make sure you wrap with []
44 $sub_delims = '!$&\'()'; // needs []
45 $pct_encoded = "%$HEXDIG$HEXDIG";
46 $r_userinfo = "(?:[$unreserved$sub_delims:]|$pct_encoded)*";
47 $r_authority = "/^(($r_userinfo)@)?(\[[^\]]+\]|[^:]*)(:(\d*))?/";
49 preg_match($r_authority, $authority, $matches);
50 $userinfo = !empty($matches[1]) ?
$matches[2] : null;
51 $host = !empty($matches[3]) ?
$matches[3] : '';
52 $port = !empty($matches[4]) ?
(int) $matches[5] : null;
54 $port = $host = $userinfo = null;
57 return new HTMLPurifier_URI(
58 $scheme, $userinfo, $host, $port, $path, $query, $fragment);