
Research
/Security News
Critical Vulnerability in NestJS Devtools: Localhost RCE via Sandbox Escape
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
Strict equality test (like ===) that handles both built-in and custom value objects (those with a valueOf function).
Egal.js provides an egal
function that tests strict equality (like
===
), but adds support for built-in and custom value
objects in a type-safe way. It also has a deepEgal
function for comparing plain objects and arrays recursively or deeply
without giving up on type-safeness on the way. It also handles circular
references.
When and why to use egal
over the triple-equals ===
operator?
==
and ===
consider two different Date
or RegExp
objects
unequal, even if they mean the same thing.valueOf
function. Egal.js
makes sure the two objects with valueOf
are actually from the same
constructor.deepEgal
.A primivitive and its boxed object equivalent are considered different.
Allowing unexpected boxed objects (e.g. new Boolean(false)
) through is risky
as they're extremely error prone (just think of !!new Boolean(false)
returning
true
). Comparing two boxed objects of the same value, on the other hand, will
work.
Non-value objects, like Array
or Object
, are compared by egal
as ===
does it — based on object identity. For recursive or deep comparison, see
deepEgal
.
NaNs (not-a-number) are not equal (matching how ===
behaves). This is
because when you compare results of two mathematical operations that may both
end up as NaN
, you might inadvertently assume the calculations went fine. If
you expect NaN
, you can use JavaScript's built-in isNaN
to test for that.
Negative and positive zeros are equal (also matching how ===
behaves).
You might end up with unexpected negative zeros via various calculations and
when you don't need to distinguish between the two, you'll end up with too many
false negatives. If you need to handle negative zeros differently, see the
article on Sameness in JavaScript.
Value objects can also return compound values. That is, you need not
return a single primitive value from valueOf
, but merely a more primitive
one. Those values are compared with deepEgal
.
function Point(x, y) { this.x = x; this.y = y }
Point.prototype.valueOf = function() { return [this.x, this.y] }
egal(new Point(42, 69), new Point(42, 69)) // => true
egal(new Point(42, 69), new Point(13, 42)) // => false
npm install egal
Egal.js doesn't yet have a build ready for the browser, but you might be able to use Browserify to have it run there till then.
Require Egal.js:
var egal = require("egal")
Then proceed with comparions:
egal(42, 42) // => true
egal(new String("Hello!"), "Hello") // => true
egal(new Date(2000, 5, 18), new Date(2000, 5, 18)) // => true
egal(/abc/i, /abc/i) // => true
To make and compare custom value objects, create a new constructor and give its
prototype a valueOf
function:
function Song(name) { this.name = name }
Song.prototype.valueOf = function() { return this.name }
egal(new Song("Play Guitar"), new Song("Play Guitar")) // => true
egal(new Song("Play Guitar"), new Song("Crumblin' Down")) // => false
Egal.js makes sure the two instances are from the same constructor before
comparing their valueOf
outputs:
function Song(name) { this.name = name }
Song.prototype.valueOf = function() { return this.name }
function Car(name) { this.name = name }
Car.prototype.valueOf = function() { return this.name }
egal(new Song("KITT"), new Car("KITT")) // => false
Objects that are instances of a class (their constructor
property set to
something other than Object
) but lack a valueOf
function, thereby not being
value objects, are compared by reference (===
).
As of v1.1.0, Egal.js comes with a recursive or deep comparison function named
deepEgal
. It was mostly extracted from the Must.js testing library's
eql
function.
var deepEgal = require("egal").deepEgal
function Model(name) { this.name = name }
deepEgal(42, 42) // => true
deepEgal({name: "John"}, {name: "John"}) // => true
deepEgal({stats: {age: 13}}, {{stats: age: 13}}) // => true
deepEgal([1, 2, 3], [1, 2, 3]) // => true
deepEgal(new Model("John"), new Model("John")) // => false
deepEgal(new Date(2000, 5), new Date(2000, 5)) // => true
The deepEgal
function compares regular primitive values, model instances and
value objects just like egal
.
Plain objects (those with no custom constructor
property in their
prototype), are compared recursively by their enumerable properties. Arrays are
compared recursively by their contents (iterating over length
). See above
about value objects for more details on plain, instances and
value objects.
Egal.js is released under a Lesser GNU Affero General Public License, which in summary means:
For more convoluted language, see the LICENSE
file.
Andri Möll typed this and the code.
Monday Calendar supported the engineering work.
If you find Egal.js needs improving, please don't hesitate to type to me now at andri@dot.ee or create an issue online.
1.3.0 (Sep 22, 2015)
deepEgal
with a custom comparison function.FAQs
Strict equality test (like ===) that handles both built-in and custom value objects (those with a valueOf function).
The npm package egal receives a total of 9,480 weekly downloads. As such, egal popularity was classified as popular.
We found that egal demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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.
Research
/Security News
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
Product
Customize license detection with Socket’s new license overlays: gain control, reduce noise, and handle edge cases with precision.
Product
Socket now supports Rust and Cargo, offering package search for all users and experimental SBOM generation for enterprise projects.