source: imaps-frontend/node_modules/fast-uri/lib/utils.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 5.7 KB
Line 
1'use strict'
2
3const { HEX } = require('./scopedChars')
4
5const IPV4_REG = /^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u
6
7function normalizeIPv4 (host) {
8 if (findToken(host, '.') < 3) { return { host, isIPV4: false } }
9 const matches = host.match(IPV4_REG) || []
10 const [address] = matches
11 if (address) {
12 return { host: stripLeadingZeros(address, '.'), isIPV4: true }
13 } else {
14 return { host, isIPV4: false }
15 }
16}
17
18/**
19 * @param {string[]} input
20 * @param {boolean} [keepZero=false]
21 * @returns {string|undefined}
22 */
23function stringArrayToHexStripped (input, keepZero = false) {
24 let acc = ''
25 let strip = true
26 for (const c of input) {
27 if (HEX[c] === undefined) return undefined
28 if (c !== '0' && strip === true) strip = false
29 if (!strip) acc += c
30 }
31 if (keepZero && acc.length === 0) acc = '0'
32 return acc
33}
34
35function getIPV6 (input) {
36 let tokenCount = 0
37 const output = { error: false, address: '', zone: '' }
38 const address = []
39 const buffer = []
40 let isZone = false
41 let endipv6Encountered = false
42 let endIpv6 = false
43
44 function consume () {
45 if (buffer.length) {
46 if (isZone === false) {
47 const hex = stringArrayToHexStripped(buffer)
48 if (hex !== undefined) {
49 address.push(hex)
50 } else {
51 output.error = true
52 return false
53 }
54 }
55 buffer.length = 0
56 }
57 return true
58 }
59
60 for (let i = 0; i < input.length; i++) {
61 const cursor = input[i]
62 if (cursor === '[' || cursor === ']') { continue }
63 if (cursor === ':') {
64 if (endipv6Encountered === true) {
65 endIpv6 = true
66 }
67 if (!consume()) { break }
68 tokenCount++
69 address.push(':')
70 if (tokenCount > 7) {
71 // not valid
72 output.error = true
73 break
74 }
75 if (i - 1 >= 0 && input[i - 1] === ':') {
76 endipv6Encountered = true
77 }
78 continue
79 } else if (cursor === '%') {
80 if (!consume()) { break }
81 // switch to zone detection
82 isZone = true
83 } else {
84 buffer.push(cursor)
85 continue
86 }
87 }
88 if (buffer.length) {
89 if (isZone) {
90 output.zone = buffer.join('')
91 } else if (endIpv6) {
92 address.push(buffer.join(''))
93 } else {
94 address.push(stringArrayToHexStripped(buffer))
95 }
96 }
97 output.address = address.join('')
98 return output
99}
100
101function normalizeIPv6 (host) {
102 if (findToken(host, ':') < 2) { return { host, isIPV6: false } }
103 const ipv6 = getIPV6(host)
104
105 if (!ipv6.error) {
106 let newHost = ipv6.address
107 let escapedHost = ipv6.address
108 if (ipv6.zone) {
109 newHost += '%' + ipv6.zone
110 escapedHost += '%25' + ipv6.zone
111 }
112 return { host: newHost, escapedHost, isIPV6: true }
113 } else {
114 return { host, isIPV6: false }
115 }
116}
117
118function stripLeadingZeros (str, token) {
119 let out = ''
120 let skip = true
121 const l = str.length
122 for (let i = 0; i < l; i++) {
123 const c = str[i]
124 if (c === '0' && skip) {
125 if ((i + 1 <= l && str[i + 1] === token) || i + 1 === l) {
126 out += c
127 skip = false
128 }
129 } else {
130 if (c === token) {
131 skip = true
132 } else {
133 skip = false
134 }
135 out += c
136 }
137 }
138 return out
139}
140
141function findToken (str, token) {
142 let ind = 0
143 for (let i = 0; i < str.length; i++) {
144 if (str[i] === token) ind++
145 }
146 return ind
147}
148
149const RDS1 = /^\.\.?\//u
150const RDS2 = /^\/\.(?:\/|$)/u
151const RDS3 = /^\/\.\.(?:\/|$)/u
152const RDS5 = /^\/?(?:.|\n)*?(?=\/|$)/u
153
154function removeDotSegments (input) {
155 const output = []
156
157 while (input.length) {
158 if (input.match(RDS1)) {
159 input = input.replace(RDS1, '')
160 } else if (input.match(RDS2)) {
161 input = input.replace(RDS2, '/')
162 } else if (input.match(RDS3)) {
163 input = input.replace(RDS3, '/')
164 output.pop()
165 } else if (input === '.' || input === '..') {
166 input = ''
167 } else {
168 const im = input.match(RDS5)
169 if (im) {
170 const s = im[0]
171 input = input.slice(s.length)
172 output.push(s)
173 } else {
174 throw new Error('Unexpected dot segment condition')
175 }
176 }
177 }
178 return output.join('')
179}
180
181function normalizeComponentEncoding (components, esc) {
182 const func = esc !== true ? escape : unescape
183 if (components.scheme !== undefined) {
184 components.scheme = func(components.scheme)
185 }
186 if (components.userinfo !== undefined) {
187 components.userinfo = func(components.userinfo)
188 }
189 if (components.host !== undefined) {
190 components.host = func(components.host)
191 }
192 if (components.path !== undefined) {
193 components.path = func(components.path)
194 }
195 if (components.query !== undefined) {
196 components.query = func(components.query)
197 }
198 if (components.fragment !== undefined) {
199 components.fragment = func(components.fragment)
200 }
201 return components
202}
203
204function recomposeAuthority (components) {
205 const uriTokens = []
206
207 if (components.userinfo !== undefined) {
208 uriTokens.push(components.userinfo)
209 uriTokens.push('@')
210 }
211
212 if (components.host !== undefined) {
213 let host = unescape(components.host)
214 const ipV4res = normalizeIPv4(host)
215
216 if (ipV4res.isIPV4) {
217 host = ipV4res.host
218 } else {
219 const ipV6res = normalizeIPv6(ipV4res.host)
220 if (ipV6res.isIPV6 === true) {
221 host = `[${ipV6res.escapedHost}]`
222 } else {
223 host = components.host
224 }
225 }
226 uriTokens.push(host)
227 }
228
229 if (typeof components.port === 'number' || typeof components.port === 'string') {
230 uriTokens.push(':')
231 uriTokens.push(String(components.port))
232 }
233
234 return uriTokens.length ? uriTokens.join('') : undefined
235};
236
237module.exports = {
238 recomposeAuthority,
239 normalizeComponentEncoding,
240 removeDotSegments,
241 normalizeIPv4,
242 normalizeIPv6,
243 stringArrayToHexStripped
244}
Note: See TracBrowser for help on using the repository browser.