(url, options)
| 54 | const wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/; |
| 55 | |
| 56 | export default function isURL(url, options) { |
| 57 | assertString(url); |
| 58 | if (!url || /[\s<>]/.test(url)) { |
| 59 | return false; |
| 60 | } |
| 61 | if (url.indexOf('mailto:') === 0) { |
| 62 | return false; |
| 63 | } |
| 64 | options = merge(options, default_url_options); |
| 65 | |
| 66 | if (options.validate_length && url.length > options.max_allowed_length) { |
| 67 | return false; |
| 68 | } |
| 69 | |
| 70 | if (!options.allow_fragments && includes(url, '#')) { |
| 71 | return false; |
| 72 | } |
| 73 | |
| 74 | if (!options.allow_query_components && (includes(url, '?') || includes(url, '&'))) { |
| 75 | return false; |
| 76 | } |
| 77 | |
| 78 | let protocol, auth, host, hostname, port, port_str, split, ipv6; |
| 79 | |
| 80 | split = url.split('#'); |
| 81 | url = split.shift(); |
| 82 | |
| 83 | split = url.split('?'); |
| 84 | url = split.shift(); |
| 85 | |
| 86 | // Replaced the 'split("://")' logic with a regex to match the protocol. |
| 87 | // This correctly identifies schemes like `javascript:` which don't use `//`. |
| 88 | // However, we need to be careful not to confuse authentication credentials (user:password@host) |
| 89 | // with protocols. A colon before an @ symbol might be part of auth, not a protocol separator. |
| 90 | const protocol_match = url.match(/^([a-z][a-z0-9+\-.]*):/i); |
| 91 | let had_explicit_protocol = false; |
| 92 | |
| 93 | const cleanUpProtocol = (potential_protocol) => { |
| 94 | had_explicit_protocol = true; |
| 95 | protocol = potential_protocol.toLowerCase(); |
| 96 | |
| 97 | if (options.require_valid_protocol && options.protocols.indexOf(protocol) === -1) { |
| 98 | // The identified protocol is not in the allowed list. |
| 99 | return false; |
| 100 | } |
| 101 | |
| 102 | // Remove the protocol from the URL string. |
| 103 | return url.substring(protocol_match[0].length); |
| 104 | }; |
| 105 | |
| 106 | if (protocol_match) { |
| 107 | const potential_protocol = protocol_match[1]; |
| 108 | const after_colon = url.substring(protocol_match[0].length); |
| 109 | |
| 110 | // Check if what follows looks like authentication credentials (user:password@host) |
| 111 | // rather than a protocol. This happens when: |
| 112 | // 1. There's no `//` after the colon (protocols like `http://` have this) |
| 113 | // 2. There's an `@` symbol before any `/` |
nothing calls this directly
no test coverage detected