Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove redundant isNaN check and add fast path for empty options #264

Merged
merged 14 commits into from
Dec 7, 2023
49 changes: 24 additions & 25 deletions cookie.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,6 @@
exports.parse = parse
exports.serialize = serialize

/**
* Module variables.
* @private
*/

const decode = decodeURIComponent
const encode = encodeURIComponent

/**
* RegExp to match field-content in RFC 7230 sec 3.2
*
Expand All @@ -61,18 +53,18 @@ const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/ // eslint-dis
* The object has the various cookies as keys(names) => values
*
* @param {string} str
* @param {object} [options]
* @param {object} opt
jsumners marked this conversation as resolved.
Show resolved Hide resolved
* @return {object}
* @public
*/

function parse (str, options) {
function parse (str, opt) {
jsumners marked this conversation as resolved.
Show resolved Hide resolved
if (typeof str !== 'string') {
throw new TypeError('argument str must be a string')
}

const result = {}
const dec = (options && options.decode) || decode
const dec = opt?.decode || decodeURIComponent

let pos = 0
let terminatorPos = 0
Expand All @@ -82,6 +74,7 @@ function parse (str, options) {
if (terminatorPos === str.length) {
break
}

terminatorPos = str.indexOf(';', pos)
terminatorPos = (terminatorPos === -1) ? str.length : terminatorPos
eqIdx = str.indexOf('=', pos)
Expand All @@ -100,12 +93,14 @@ function parse (str, options) {
? str.substring(eqIdx + 1, terminatorPos - 1).trim()
: str.substring(eqIdx, terminatorPos).trim()

result[key] = (dec !== decode || val.indexOf('%') !== -1)
result[key] = (dec !== decodeURIComponent || val.indexOf('%') !== -1)
? tryDecode(val, dec)
: val
}

pos = terminatorPos + 1
}

return result
}

Expand All @@ -125,30 +120,33 @@ function parse (str, options) {
* @public
*/

function serialize (name, val, options) {
const opt = options || {}
const enc = opt.encode || encode
if (typeof enc !== 'function') {
throw new TypeError('option encode is invalid')
function serialize (name, val, opt) {
if (name.length && !fieldContentRegExp.test(name)) {
throw new TypeError('argument name is invalid')
}

if (!fieldContentRegExp.test(name)) {
throw new TypeError('argument name is invalid')
const enc = opt?.encode || encodeURIComponent
if (typeof enc !== 'function') {
throw new TypeError('option encode is invalid')
}

const value = enc(val)
if (value && !fieldContentRegExp.test(value)) {
if (value.length && !fieldContentRegExp.test(value)) {
throw new TypeError('argument val is invalid')
}

let str = name + '=' + value

if (opt == null) return str

if (opt.maxAge != null) {
const maxAge = opt.maxAge - 0
if (isNaN(maxAge) || !isFinite(maxAge)) {
const maxAge = +opt.maxAge

if (!isFinite(maxAge)) {
throw new TypeError('option maxAge is invalid')
}

str += '; Max-Age=' + Math.floor(maxAge)
str += '; Max-Age=' + Math.trunc(maxAge)
}

if (opt.domain) {
Expand Down Expand Up @@ -193,6 +191,7 @@ function serialize (name, val, options) {
const sameSite = typeof opt.sameSite === 'string'
? opt.sameSite.toLowerCase()
: opt.sameSite

switch (sameSite) {
case true:
str += '; SameSite=Strict'
Expand All @@ -219,13 +218,13 @@ function serialize (name, val, options) {
*
* @param {string} str
* @param {function} decode
* @returns {string}
* @private
*/

function tryDecode (str, decode) {
try {
return decode(str)
} catch (e) {
} catch {
return str
}
}