• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const {
4  Array,
5} = primordials;
6
7const { ERR_INVALID_URI } = require('internal/errors').codes;
8
9const hexTable = new Array(256);
10for (let i = 0; i < 256; ++i)
11  hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
12
13const isHexTable = [
14  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15
15  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31
16  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32 - 47
17  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63
18  0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 64 - 79
19  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80 - 95
20  0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 96 - 111
21  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 112 - 127
22  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 128 ...
23  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  // ... 256
30];
31
32function encodeStr(str, noEscapeTable, hexTable) {
33  const len = str.length;
34  if (len === 0)
35    return '';
36
37  let out = '';
38  let lastPos = 0;
39  let i = 0;
40
41  outer:
42  for (; i < len; i++) {
43    let c = str.charCodeAt(i);
44
45    // ASCII
46    while (c < 0x80) {
47      if (noEscapeTable[c] !== 1) {
48        if (lastPos < i)
49          out += str.slice(lastPos, i);
50        lastPos = i + 1;
51        out += hexTable[c];
52      }
53
54      if (++i === len)
55        break outer;
56
57      c = str.charCodeAt(i);
58    }
59
60    if (lastPos < i)
61      out += str.slice(lastPos, i);
62
63    // Multi-byte characters ...
64    if (c < 0x800) {
65      lastPos = i + 1;
66      out += hexTable[0xC0 | (c >> 6)] +
67             hexTable[0x80 | (c & 0x3F)];
68      continue;
69    }
70    if (c < 0xD800 || c >= 0xE000) {
71      lastPos = i + 1;
72      out += hexTable[0xE0 | (c >> 12)] +
73             hexTable[0x80 | ((c >> 6) & 0x3F)] +
74             hexTable[0x80 | (c & 0x3F)];
75      continue;
76    }
77    // Surrogate pair
78    ++i;
79
80    // This branch should never happen because all URLSearchParams entries
81    // should already be converted to USVString. But, included for
82    // completion's sake anyway.
83    if (i >= len)
84      throw new ERR_INVALID_URI();
85
86    const c2 = str.charCodeAt(i) & 0x3FF;
87
88    lastPos = i + 1;
89    c = 0x10000 + (((c & 0x3FF) << 10) | c2);
90    out += hexTable[0xF0 | (c >> 18)] +
91           hexTable[0x80 | ((c >> 12) & 0x3F)] +
92           hexTable[0x80 | ((c >> 6) & 0x3F)] +
93           hexTable[0x80 | (c & 0x3F)];
94  }
95  if (lastPos === 0)
96    return str;
97  if (lastPos < len)
98    return out + str.slice(lastPos);
99  return out;
100}
101
102module.exports = {
103  encodeStr,
104  hexTable,
105  isHexTable
106};
107