Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Stringify JS values
npm install --save seroval
yarn add seroval
pnpm add seroval
import { serialize } from 'seroval';
const object = {
number: [Math.random(), -0, NaN, Infinity, -Infinity],
string: ['hello world', '<script>Hello World</script>'],
boolean: [true, false],
null: null,
undefined: undefined,
bigint: 9007199254740991n,
array: [,,,], // holes
regexp: /[a-z0-9]+/i,
date: new Date(),
map: new Map([['hello', 'world']]),
set: new Set(['hello', 'world']),
};
// self cyclic references
// recursive objects
object.self = object;
// recursive arrays
object.array.push(object.array);
// recursive maps
object.map.set('self', object.map);
// recursive sets
object.set.add(object.set);
// mutual cyclic references
object.array.push(object.map);
object.map.set('mutual', object.set);
object.set.add(object.array);
const result = serialize(object);
console.log(result);
Output (as a string):
((h,j,k,m)=>(m={number:[0.9039984824241858,-0,NaN,1/0,-1/0],string:["hello world","\x3Cscript>Hello World\x3C/script>"],boolean:[!0,!1],null:null,undefined:void 0,bigint:9007199254740991n,array:h=[,,,,j=new Map([["hello","world"],["mutual",k=new Set(["hello","world"])]])],regexp:/[a-z0-9]+/i,date:new Date("2023-03-16T11:57:24.849Z"),map:j,set:k},h[3]=h,j.set("self",j),k.add(k).add(h),m.self=m,m))()
// Formatted for readability
((h, j, k, m) => (m = {
number: [0.9039984824241858, -0, NaN, 1 / 0, -1 / 0],
string: ["hello world", "\x3Cscript>Hello World\x3C/script>"],
boolean: [!0, !1],
null: null,
undefined: void 0,
bigint: 9007199254740991n,
array: h = [, , , , j = new Map([
["hello", "world"],
["mutual", k = new Set(["hello", "world"])]
])],
regexp: /[a-z0-9]+/i,
date: new Date("2023-03-16T11:57:24.849Z"),
map: j,
set: k
}, h[3] = h, j.set("self", j), k.add(k).add(h), m.self = m, m))()
import { serialize } from 'seroval';
const a = new Map([['name', 'a']]);
const b = new Map([['name', 'b']]);
const c = new Map([['name', 'c']]);
const d = new Map([['name', 'd']]);
c.set('left', a);
d.set('left', a);
c.set('right', b);
d.set('right', b);
a.set('children', [c, d]);
b.set('children', [c, d]);
const result = serialize({ a, b, c, d });
console.log(result);
Output (as a string):
((h,j,k,m,o,q)=>(q={a:h=new Map([["name","a"],["children",[j=new Map([["name","c"],["right",o=new Map([["name","b"],["children",k=[,m=new Map([["name","d"]])]]])]]),m]]]),b:o,c:j,d:m},j.set("left",h),k[0]=j,m.set("left",h).set("right",o),q))()
// Formatted
((h, j, k, m, o, q) => (q = {
a: h = new Map([
["name", "a"],
["children", [j = new Map([
["name", "c"],
["right", o = new Map([
["name", "b"],
["children", k = [, m = new Map([
["name", "d"]
])]]
])]
]), m]]
]),
b: o,
c: j,
d: m
}, j.set("left", h), k[0] = j, m.set("left", h).set("right", o), q))()
import { serialize, deserialize } from 'seroval';
const value = undefined;
console.log(deserialize(serialize(value)) === value);
serialize
and deserialize
is great for server-to-client communication, but what about the other way? serialize
may cause an RCE if used as a payload for requests. seroval
includes toJSON
and fromJSON
as an alternative form of serialization.
First example above outputs the following JSON
import { toJSON } from 'seroval';
// ...
const result = toJSON(object);
console.log(JSON.stringify(result));
{"t":{"t":8,"i":0,"d":{"k":["number","string","boolean","null","undefined","bigint","array","regexp","date","map","set","self"],"v":[{"t":7,"i":1,"a":[{"t":0,"s":0.7047255726239685},{"t":0,"s":"-0"},{"t":0,"s":null},{"t":0,"s":"1/0"},{"t":0,"s":"-1/0"}]},{"t":7,"i":2,"a":[{"t":0,"s":"\"hello world\""},{"t":0,"s":"\"\\x3Cscript>Hello World\\x3C/script>\""}]},{"t":7,"i":3,"a":[{"t":0,"s":"!0"},{"t":0,"s":"!1"}]},{"t":0,"s":null},{"t":0,"s":"void 0"},{"t":1,"s":"9007199254740991n"},{"t":7,"i":4,"a":[null,null,null,{"t":2,"i":4},{"t":6,"i":5,"d":{"k":[{"t":0,"s":"\"hello\""},{"t":0,"s":"\"self\""},{"t":0,"s":"\"mutual\""}],"v":[{"t":0,"s":"\"world\""},{"t":2,"i":5},{"t":5,"i":6,"a":[{"t":0,"s":"\"hello\""},{"t":0,"s":"\"world\""},{"t":2,"i":6},{"t":2,"i":4}]}],"s":3}}]},{"t":4,"i":7,"s":"/[a-z0-9]+/i"},{"t":3,"i":8,"s":"2023-03-16T12:01:29.836Z"},{"t":2,"i":5},{"t":2,"i":6},{"t":2,"i":0}],"s":12}},"r":0,"i":true,"f":8191,"m":[4,5,6,0]}
Then you can feed it to fromJSON
:
import { fromJSON } from 'seroval';
const revived = fromJSON(result);
Alternatively, if you want to compile the JSON output to JS (like deserialize
), you can use compileJSON
import { compileJSON, deserialize } from 'seroval';
const code = compileJSON(result);
const revived = deserialize(code);
seroval
allows Promise serialization through serializeAsync
and toJSONAsync
.
import { serializeAsync } from 'seroval';
const value = Promise.resolve(100);
const result = await serializeAsync(value); // "Promise.resolve(100)"
console.log(await deserialize(result)); // 100
Note
seroval
can only serialize the resolved value and so the output will always be usingPromise.resolve
. If the Promise fulfills with rejection, the rejected value is thrown before serialization happens.
The following values are the only values accepted by seroval
:
NaN
Infinity
-Infinity
-0
number
string
boolean
null
undefined
bigint
Array
+ holesObject
RegExp
Date
Map
Set
TypedArray
Int8Array
Int16Array
Int32Array
Uint8Array
Uint16Array
Uint32Array
Uint8ClampedArray
Float32Array
Float64Array
BigInt64Array
BigUint64Array
Error
AggregateError
EvalError
RangeError
ReferenceError
SyntaxError
TypeError
URIError
Promise
(with serializeAsync
)Iterable
serialize
, serializeAsync
, toJSON
and toJSONAsync
can accept a { disabledFeatures: number }
option. The disabledFeatures
defines how various code output of serialize
, serializeAsync
and compileJSON
.
import { serialize, Feature } from 'seroval';
const y = Object.create(null);
y.self = y;
y.example = 'Hello World';
function serializeWithTarget(value, disabledFeatures) {
const result = serialize(value, {
disabledFeatures,
});
console.log(result);
}
serializeWithTarget(y, Feature.ArrowFunction | Feature.ObjectAssign);
serializeWithTarget(y, 0);
(function(h){return (h=Object.create(null),h.self=h,h.example="Hello World",h)})()
(h=>(h=Object.assign(Object.create(null),{example:"Hello World"}),h.self=h,h))()
disabledFeatures
uses bit flags for faster checking, so if you need to disable multiple features, you can use the logical OR symbol (|
).
Here's an ES2017
flag:
import { serialize, Feature } from 'seroval';
const ES2017FLAG =
Feature.AggregateError // ES2021
| Feature.BigInt // ES2020
| Feature.BigIntTypedArray // ES2020;
serialize(myValue, {
disabledFeatures: ES2017FLAG,
})
By default, all feature flags are enabled. The following are the feature flags and their behavior when disabled:
AggregateError
Error
instead.ArrayPrototypeValues
Symbol.iterator
instead (if SymbolIterator
is not set).ArrowFunction
MethodShortand
is not set) or function expressions for iterables.BigInt
BigIntTypedArray
ErrorPrototypeStack
Map
MethodShorthand
ObjectAssign
Promise
serializeAsync
and toJSONAsync
.Set
SymbolIterator
TypedArray
BigIntTypedArray
BigInt
is disabled.MIT © lxsmnsyc
FAQs
Stringify JS values
The npm package seroval receives a total of 167,080 weekly downloads. As such, seroval popularity was classified as popular.
We found that seroval demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.