123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- import {asciiAlphanumeric} from 'micromark-util-character'
- import {encode} from 'micromark-util-encode'
- export function sanitizeUri(url, protocol) {
- const value = encode(normalizeUri(url || ''))
- if (!protocol) {
- return value
- }
- const colon = value.indexOf(':')
- const questionMark = value.indexOf('?')
- const numberSign = value.indexOf('#')
- const slash = value.indexOf('/')
- if (
-
- colon < 0 ||
-
- (slash > -1 && colon > slash) ||
- (questionMark > -1 && colon > questionMark) ||
- (numberSign > -1 && colon > numberSign) ||
-
- protocol.test(value.slice(0, colon))
- ) {
- return value
- }
- return ''
- }
- export function normalizeUri(value) {
-
- const result = []
- let index = -1
- let start = 0
- let skip = 0
- while (++index < value.length) {
- const code = value.charCodeAt(index)
-
- let replace = ''
-
- if (
- code === 37 &&
- asciiAlphanumeric(value.charCodeAt(index + 1)) &&
- asciiAlphanumeric(value.charCodeAt(index + 2))
- ) {
- skip = 2
- }
-
- else if (code < 128) {
- if (!/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(code))) {
- replace = String.fromCharCode(code)
- }
- }
-
- else if (code > 55_295 && code < 57_344) {
- const next = value.charCodeAt(index + 1)
-
- if (code < 56_320 && next > 56_319 && next < 57_344) {
- replace = String.fromCharCode(code, next)
- skip = 1
- }
-
- else {
- replace = '\uFFFD'
- }
- }
-
- else {
- replace = String.fromCharCode(code)
- }
- if (replace) {
- result.push(value.slice(start, index), encodeURIComponent(replace))
- start = index + skip + 1
- replace = ''
- }
- if (skip) {
- index += skip
- skip = 0
- }
- }
- return result.join('') + value.slice(start)
- }
|