import { LinkParser } from '../inline';
import { textlink, medialink } from './link';
import { union, some } from '../../combinator';
import { Input, input } from '../context';
import { inspect } from '../../debug.test';
describe('Unit: parser/inline/link', () => {
describe('link', () => {
const link: LinkParser = union([
medialink,
textlink,
]);
const parser = some(link);
it('xss', () => {
assert.deepStrictEqual(inspect(parser, input('[]{javascript:alert}')), [['javascript:alert'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{vbscript:alert}')), [['vbscript:alert'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K}')), [['data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{any:alert}')), [['any:alert'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{"}')), [['"'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{<}')), [['<'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{\\}')), [['\\'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{\\"}')), [['\\"'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{\\<}')), [['\\<'], '']);
});
it('fishing', () => {
assert.deepStrictEqual(inspect(parser, input('[http://host]{http://evil}')), [['http://host'], '']);
assert.deepStrictEqual(inspect(parser, input('[\\http://host]{http://evil}')), [['http://host'], '']);
assert.deepStrictEqual(inspect(parser, input('[https://host]{http://host}')), [['https://host'], '']);
assert.deepStrictEqual(inspect(parser, input('[[]{http://host}.com]{http://host}')), [['[]{http://host}.com'], '']);
assert.deepStrictEqual(inspect(parser, input('[[]{http://host/a}b]{http://host/ab}')), [['[]{http://host/a}b'], '']);
assert.deepStrictEqual(inspect(parser, input('{http%73://host}')), [['http%73://host'], '']);
assert.deepStrictEqual(inspect(parser, input('{http://a%C3%A1}')), [['http://a%C3%A1'], '']);
assert.deepStrictEqual(inspect(parser, input('[http://á]{http://evil}')), [['http://á'], '']);
assert.deepStrictEqual(inspect(parser, input('[xxx://á]{http://evil}')), [['xxx://á'], '']);
assert.deepStrictEqual(inspect(parser, input('[mailto:á]{http://evil}')), [['mailto:á'], '']);
assert.deepStrictEqual(inspect(parser, input('[file:///]{http://evil}')), [['file:///'], '']);
assert.deepStrictEqual(inspect(parser, input('[.http://á]{http://evil}')), [['.http://á'], '']);
assert.deepStrictEqual(inspect(parser, input('[0987654321]{tel:1234567890}')), [['0987654321'], '']);
assert.deepStrictEqual(inspect(parser, input('[1234567890-]{tel:1234567890}')), [['1234567890-'], '']);
assert.deepStrictEqual(inspect(parser, input('[-1234567890]{tel:1234567890}')), [['-1234567890'], '']);
assert.deepStrictEqual(inspect(parser, input('[123456789a]{tel:1234567890}')), [['123456789a'], '']);
assert.deepStrictEqual(inspect(parser, input('[1234567890]{tel:ttel:1234567890}')), [['1234567890'], '']);
assert.deepStrictEqual(inspect(parser, input('[#a]{b}')), [['#a'], '']);
assert.deepStrictEqual(inspect(parser, input('[\\#a]{b}')), [['#a'], '']);
assert.deepStrictEqual(inspect(parser, input('[c #a]{b}')), [['c #a'], '']);
assert.deepStrictEqual(inspect(parser, input('[c \\#a]{b}')), [['c #a'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{#a}')), [['#a'], '']);
assert.deepStrictEqual(inspect(parser, input('[@a]{b}')), [['@a'], '']);
assert.deepStrictEqual(inspect(parser, input('[\\@a]{b}')), [['@a'], '']);
assert.deepStrictEqual(inspect(parser, input('[c @a]{b}')), [['c @a'], '']);
assert.deepStrictEqual(inspect(parser, input('[c \\@a]{b}')), [['c @a'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{@a}')), [['@a'], '']);
});
it('invalid', () => {
assert.deepStrictEqual(inspect(parser, input('')), undefined);
assert.deepStrictEqual(inspect(parser, input('{}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]{}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]{ }')), [['[]{ }'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{ }')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]{ }')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]{{}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]{}}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]{{}}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]{{b}}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]{b\nc}')), [['[]{b'], '\nc}']);
assert.deepStrictEqual(inspect(parser, input('[]{b\\\nc}')), [['[]{b\\'], '\nc}']);
assert.deepStrictEqual(inspect(parser, input('[]{ b}')), [['[]{ b}'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{ b\n}')), [['[]{ b'], '\n}']);
assert.deepStrictEqual(inspect(parser, input('[ ]{}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[ ]{ }')), undefined);
assert.deepStrictEqual(inspect(parser, input('[ ]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[ ]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[ a]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[ a ]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[\\ a]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[ \\ a]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[\n]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[\\ ]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[\\\n]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[	]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[[]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[a]{}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[a\nb]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[a\\\nb]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[*a\nb*]{/}')), undefined);
assert.deepStrictEqual(inspect(parser, input('[http://host]{http://host}')), [['http://host'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{ttp://host}')), [['ttp://host'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{http://[::ffff:0:0%1]}')), [['http://[::ffff:0:0%1]'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{http://[::ffff:0:0/96]}')), [['http://[::ffff:0:0/96]'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/.}')), [[`^/.`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/..}')), [[`^/..`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/../}')), [[`^/../`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/../..}')), [[`^/../..`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/../b}')), [[`^/../b`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/../b/..}')), [[`^/../b/..`], '']);
assert.deepStrictEqual(inspect(parser, input(' []{b}')), undefined);
assert.deepStrictEqual(inspect(parser, input('![]{/}')), undefined);
});
it('basic', () => {
assert.deepStrictEqual(inspect(parser, input('[]{b}')), [['b'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{b }')), [['b'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{b }')), [['[]{b'], ' }']);
assert.deepStrictEqual(inspect(parser, input('[]{ b }')), [['b'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{ b }')), [['[]{ b'], ' }']);
assert.deepStrictEqual(inspect(parser, input('[]{ b }')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]{ b }')), undefined);
assert.deepStrictEqual(inspect(parser, input('[]{"}')), [[`"`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{"}"}')), [[`"`], '"}']);
assert.deepStrictEqual(inspect(parser, input('[]{\\}')), [[`\\`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{\\ }')), [[`\\`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{\\b}')), [[`\\b`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{?b=c+d&\\#}')), [['?b=c+d&\\#'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{?©}')), [['?©'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{#}')), [['#'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{#b}')), [['#b'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{./b}')), [['./b'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b}')), [[`^/b`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b?/../}')), [[`^/b?/../`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b#/../}')), [[`^/b#/../`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b}', new Input({ host: new URL('/dir', location.origin) }))), [[`^/b`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b}', new Input({ host: new URL('/dir/', location.origin) }))), [[`^/b`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b}', new Input({ host: new URL('/folder/doc.md', location.origin) }))), [[`^/b`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b}', new Input({ host: new URL('/folder/doc.md/', location.origin) }))), [[`^/b`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b}', new Input({ host: new URL('/.file', location.origin) }))), [[`^/b`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b}', new Input({ host: new URL('/0.0a', location.origin) }))), [[`^/b`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b}', new Input({ host: new URL('/0.a0', location.origin) }))), [[`^/b`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b}', new Input({ host: new URL('/0.0', location.origin) }))), [[`^/b`], '']);
assert.deepStrictEqual(inspect(parser, input('[]{^/b}', new Input({ host: new URL('/0.0,0.0,0z', location.origin) }))), [[`^/b`], '']);
assert.deepStrictEqual(inspect(parser, input('[a ]{b}')), [['a'], '']);
assert.deepStrictEqual(inspect(parser, input('[a ]{b}')), [['a'], '']);
assert.deepStrictEqual(inspect(parser, input('[a]{b}')), [['a'], '']);
assert.deepStrictEqual(inspect(parser, input('[a]{#}')), [['a'], '']);
assert.deepStrictEqual(inspect(parser, input('[a]{#b}')), [['a'], '']);
assert.deepStrictEqual(inspect(parser, input('[a b]{c}')), [['a b'], '']);
assert.deepStrictEqual(inspect(parser, input(`[]{?#${encodeURIComponent(':/[]{}<>?#=& ')}}`)), [['?#%3A%2F[]{}<>%3F%23%3D%26%20'], '']);
assert.deepStrictEqual(inspect(parser, input('{b}')), [['b'], '']);
assert.deepStrictEqual(inspect(parser, input('{ ][ }')), [[']['], '']);
assert.deepStrictEqual(inspect(parser, input('{ }{ }')), [['}{'], '']);
assert.deepStrictEqual(inspect(parser, input('{Http://host}')), [['Http://host'], '']);
});
it('tel', () => {
assert.deepStrictEqual(inspect(parser, input('{tel:1234567890}')), [[`tel:1234567890`], '']);
assert.deepStrictEqual(inspect(parser, input('{Tel:1234567890}')), [[`Tel:1234567890`], '']);
assert.deepStrictEqual(inspect(parser, input('{tel:+1234567890}')), [[`tel:+1234567890`], '']);
assert.deepStrictEqual(inspect(parser, input('{tel:+12-345-67-890}')), [[`tel:+12-345-67-890`], '']);
assert.deepStrictEqual(inspect(parser, input('[1234567890]{tel:1234567890}')), [[`1234567890`], '']);
assert.deepStrictEqual(inspect(parser, input('[1234567890]{tel:12-3456-7890}')), [[`1234567890`], '']);
assert.deepStrictEqual(inspect(parser, input('[12-3456-7890]{tel:1234567890}')), [[`12-3456-7890`], '']);
assert.deepStrictEqual(inspect(parser, input('[+12-34567-890]{tel:+12-345-67890}')), [[`+12-34567-890`], '']);
});
it('media', () => {
assert.deepStrictEqual(inspect(parser, input('[![]{a}]{a}')), [['
'], '']);
assert.deepStrictEqual(inspect(parser, input('[![]{a}]{b}')), [['
'], '']);
assert.deepStrictEqual(inspect(parser, input('[![]{a} ]{b}')), [['![]{a}'], '']);
assert.deepStrictEqual(inspect(parser, input('[![]{a}![]{a}]{b}')), [['![]{a}![]{a}'], '']);
assert.deepStrictEqual(inspect(parser, input('[[![]{a}]{b}]{c}')), [['[![]{a}]{b}'], '']);
assert.deepStrictEqual(inspect(parser, input('[!http://host]{b}')), [['
'], '']);
});
it('nest', () => {
assert.deepStrictEqual(inspect(parser, input('[*]{/}')), [['*'], '']);
assert.deepStrictEqual(inspect(parser, input('[\\[]{/}')), [['['], '']);
assert.deepStrictEqual(inspect(parser, input('[\\]]{/}')), [[']'], '']);
assert.deepStrictEqual(inspect(parser, input('[[]{a}]{a}')), [['[]{a}'], '']);
assert.deepStrictEqual(inspect(parser, input('[[]{a}]{b}')), [['[]{a}'], '']);
assert.deepStrictEqual(inspect(parser, input('[[![]{a}]{a}]{a}')), [['[![]{a}]{a}'], '']);
assert.deepStrictEqual(inspect(parser, input('[[![]{a}]{a}]{b}')), [['[![]{a}]{a}'], '']);
assert.deepStrictEqual(inspect(parser, input('[[![]{a}]{b}]{b}')), [['[![]{a}]{b}'], '']);
assert.deepStrictEqual(inspect(parser, input('[((a))]{b}')), [['((a))'], '']);
assert.deepStrictEqual(inspect(parser, input('[[[a]]]{b}')), [['[[a]]'], '']);
assert.deepStrictEqual(inspect(parser, input('[#a]{b}')), [['#a'], '']);
assert.deepStrictEqual(inspect(parser, input('[@a]{b}')), [['@a'], '']);
assert.deepStrictEqual(inspect(parser, input('[@a@b]{c}')), [['@a@b'], '']);
assert.deepStrictEqual(inspect(parser, input('[a@b]{c}')), [['a@b'], '']);
assert.deepStrictEqual(inspect(parser, input('[==a==]{b}')), [['a'], '']);
assert.deepStrictEqual(inspect(parser, input('[*a*]{b}')), [['a'], '']);
});
it('external', () => {
assert.deepStrictEqual(inspect(parser, input('[]{//host}')), [['//host'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{//[::]}')), [['//[::]'], '']);
});
it('attribute', () => {
assert.deepStrictEqual(inspect(parser, input('[]{/ name=}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ name="}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ name="""}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ name}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ name=""}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ name=" "}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ name="\\""}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ __proto__}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ constructor}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ rel="prefetch"}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ aspect-ratio="4/3"}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ 4:3}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ =}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/\nname}')), [['[]{/'], '\nname}']);
});
it('nofollow', () => {
assert.deepStrictEqual(inspect(parser, input('[]{/ nofollow=}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ nofollow=nofollow}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ nofollow=""}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ nofollow="nofollow"}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ nofollow nofollow}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ nofollow}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ nofollow }')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{/ nofollow }')), [['[]{/ nofollow'], ' }']);
assert.deepStrictEqual(inspect(parser, input('[]{/ nofollow}')), [['[]{/'], ' nofollow}']);
assert.deepStrictEqual(inspect(parser, input('[]{ / nofollow}')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{ / nofollow }')), [['/'], '']);
assert.deepStrictEqual(inspect(parser, input('[]{ / nofollow }')), [['[]{ / nofollow'], ' }']);
assert.deepStrictEqual(inspect(parser, input('[]{ / nofollow}')), [['[]{ /'], ' nofollow}']);
assert.deepStrictEqual(inspect(parser, input('[]{http://host nofollow}')), [['http://host'], '']);
assert.deepStrictEqual(inspect(parser, input('[!http://host]{http://host nofollow}')), [['
'], '']);
});
});
});