You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.2 KiB
JavaScript

'use strict'
const decodeText = require('./decodeText')
const RE_ENCODED = /%([a-fA-F0-9]{2})/g
function encodedReplacer (match, byte) {
return String.fromCharCode(parseInt(byte, 16))
}
function parseParams (str) {
const res = []
let state = 'key'
let charset = ''
let inquote = false
let escaping = false
let p = 0
let tmp = ''
for (var i = 0, len = str.length; i < len; ++i) { // eslint-disable-line no-var
const char = str[i]
if (char === '\\' && inquote) {
if (escaping) { escaping = false } else {
escaping = true
continue
}
} else if (char === '"') {
if (!escaping) {
if (inquote) {
inquote = false
state = 'key'
} else { inquote = true }
continue
} else { escaping = false }
} else {
if (escaping && inquote) { tmp += '\\' }
escaping = false
if ((state === 'charset' || state === 'lang') && char === "'") {
if (state === 'charset') {
state = 'lang'
charset = tmp.substring(1)
} else { state = 'value' }
tmp = ''
continue
} else if (state === 'key' &&
(char === '*' || char === '=') &&
res.length) {
if (char === '*') { state = 'charset' } else { state = 'value' }
res[p] = [tmp, undefined]
tmp = ''
continue
} else if (!inquote && char === ';') {
state = 'key'
if (charset) {
if (tmp.length) {
tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
'binary',
charset)
}
charset = ''
} else if (tmp.length) {
tmp = decodeText(tmp, 'binary', 'utf8')
}
if (res[p] === undefined) { res[p] = tmp } else { res[p][1] = tmp }
tmp = ''
++p
continue
} else if (!inquote && (char === ' ' || char === '\t')) { continue }
}
tmp += char
}
if (charset && tmp.length) {
tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
'binary',
charset)
} else if (tmp) {
tmp = decodeText(tmp, 'binary', 'utf8')
}
if (res[p] === undefined) {
if (tmp) { res[p] = tmp }
} else { res[p][1] = tmp }
return res
}
module.exports = parseParams