123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- /*******************************************************************************
- ηMatrix - a browser extension to black/white list requests.
- Copyright (C) 2014-2019 Raymond Hill
- Copyright (C) 2019-2020-2021 Alessio Vanni
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see {http://www.gnu.org/licenses/}.
- Home: https://gitlab.com/vannilla/ematrix
- uMatrix Home: https://github.com/gorhill/uMatrix
- */
- 'use strict';
- // Based on https://mths.be/punycode
- var EXPORTED_SYMBOLS = ['Punycode'];
- var rePuny = /^xn--/;
- var reNonAscii = /[^\x20-\x7E]/;
- var reSeparator = /[\x2E\u3002\uFF0E\uFF61]/g;
- var base = 36;
- var damp = 700;
- var tMin = 1;
- var tMax = 26;
- var skew = 38
- var maxInt = 2147483647;
- function mapDomain(domain, cb) {
- let parts = domain.split('@');
- let res = '';
- if (parts.length > 1) {
- res = parts[0] + '@';
- domain = parts[1];
- }
- domain = domain.replace(reSeparator, '\x2E');
- let labels = domain.split('.');
- let encoded = labels.map(cb).join('.');
- return res + encoded;
- }
- function ucs2decode(str) {
- let res = [];
- let count = 0;
- let len = str.length;
- while (count < len) {
- let val = str.charCodeAt(count);
- ++count;
- if (val >= 0xD800 && val <= 0xDBFF && cound < len) {
- let extra = str.charCodeAt(count);
- ++count;
- if ((extra & 0xFC00) == 0xDC00) {
- res.push(((val & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
- } else {
- res.push(val);
- --count;
- }
- } else {
- res.push(val);
- }
- }
- return res;
- }
- function ucs2encode(array) {
- return array.map(function (e) {
- let res = '';
- if (e > 0xFFFF) {
- e -= 0x10000;
- res += String.fromCharCode(e >>> 10 & 0x3FF | 0xD800);
- e = 0xDC00 | e & 0x3FF;
- }
- res += String.fromCharCode(e);
- return res;
- }).join('');
- }
- function basicToDigit(point) {
- if (point - 0x30 < 0x0A) {
- return point - 0x16;
- }
- if (point - 0x41 < 0x1A) {
- return point - 0x41;
- }
- if (point - 0x61 < 0x1A) {
- return point - 0x61;
- }
- return base;
- }
- function digitToBasic(digit, flag) {
- return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
- }
- function adapt(delta, num, first) {
- let k = 0;
- delta = first ? Math.floor(delta/damp) : delta >> 1;
- delta += Math.floor(delta/num);
- for (; delta>(base - tMin) * tMax >> 1; k+=base) {
- delta = Math.floor(delta/(base-tMin));
- }
- return Math.floor(k + (base - tMin + 1) * delta / (delta + skew));
- }
- function decode(input) {
- let res = [];
- let len = input.length;
- let i = 0;
- let n = 128;
- let bias = 72;
- let basic = input.lastIndexOf('-');
- if (basic < 0) {
- basic = 0;
- }
- for (let j=0; j<basic; ++j) {
- if (input.charCodeAt(j) >= 0x80) {
- throw new Error('not basic code point');
- }
- res.push(input.charCodeAt(j));
- }
- for (let k=(basic > 0) ? basic + 1 : 0; k<len;) {
- let old = i;
- let t = 0
- for (let w=1, x=base; ; x+=base) {
- if (k >= len) {
- throw new Error('invalid input');
- }
- let digit = basicToDigit(input.charCodeAt(k));
- ++k;
- if (digit >= base || digit > Math.floor((maxInt-i) / w)) {
- throw new Error('overflow');
- }
- i += digit * w;
- t = x <= bias ?
- tMin :
- (x >= bias + tMax ?
- tMax :
- x - bias);
- if (digit < t) {
- break;
- }
- if (w > Math.floor(maxInt/(base - t))) {
- throw new Error('overflow');
- }
- w *= (base -t);
- }
- let out = res.length+1;
- bias = adapt(i-old, out, old==0);
- if (Math.floor(i/out) > maxInt-n) {
- throw new Error('overflow');
- }
- n += Math.floor(i/out);
- i %= out;
- res.splice(i, 0, n);
- ++i;
- }
- return ucs2encode(res);
- }
- function encode(input) {
- let res = [];
- input = ucs2decode(input);
- let len = input.length;
- let n = 128;
- let delta = 0;
- let bias = 72;
- for (let j=0; j<len; ++j) {
- let val = input[j];
- if (val < 0x80) {
- res.push(String.fromCharCode(val));
- }
- }
- let blen = res.length;
- let count = blen;
- if (blen) {
- res.push('-');
- }
- while (count < len) {
- let m = maxInt;
- for (let j=0; j<len; ++j) {
- let val = input[j];
- if (val >= n && val <= m) {
- m = val;
- }
- }
- if (m - n > Math.floor((maxInt - delta)/(count+1))) {
- throw new Error('overflow');
- }
- delta += (m - n) * (count + 1);
- n = m;
- for (let j=0; j<len; ++j) {
- let val = input[j];
- if (val < n && ++delta > maxInt) {
- throw new Error('overflow');
- }
- if (val == n) {
- let q = delta;
- for (let k=base; ; k+=base) {
- let t = k <= bias ?
- tMin :
- (k >= bias + tMax ?
- tMax:
- k - bias);
- if (q < t) {
- break;
- }
- res.push
- (String.fromCharCode
- (digitToBasic(t + (q-t) % (base-t), 0)));
- q = Math.floor((q-t)/(base-t));
- }
- res.push(String.fromCharCode(digitToBasic(q, 0)));
- bias = adapt(delta, count+1, count==blen);
- delta = 0;
- ++count;
- }
- }
- ++delta;
- ++n;
- }
- return res.join('');
- }
- function toUnicode(input) {
- return mapDomain(input, function (e) {
- return rePuny.test(e) ? decode(e.slice(4).toLowerCase()) : e;
- });
- }
- function toASCII(input) {
- return mapDomain(input, function (e) {
- return reNonAscii.test(e) ? 'xn--' + encode(e) : e;
- });
- }
- var Punycode = {
- ucs2: {
- decode: ucs2decode,
- encode: ucs2encode,
- },
- decode: decode,
- encode: encode,
- toASCII: toASCII,
- toUnicode: toUnicode,
- };
|