summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRuben Bridgewater <ruben@bridgewater.de>2018-12-04 00:02:51 +0100
committerRich Trott <rtrott@gmail.com>2018-12-10 14:32:17 -0800
commit9fb4fa8ded0504f63c89ed969640e5a2df8d0d59 (patch)
tree3002d368f6449a896b1a5c3d08bbe394dc08f872 /lib
parentd695a019ae44da50e5d54e9fa8a42a3ae0abe3cd (diff)
downloadandroid-node-v8-9fb4fa8ded0504f63c89ed969640e5a2df8d0d59.tar.gz
android-node-v8-9fb4fa8ded0504f63c89ed969640e5a2df8d0d59.tar.bz2
android-node-v8-9fb4fa8ded0504f63c89ed969640e5a2df8d0d59.zip
assert,util: harden comparison
The former algorithm used checks which were unsafe. Most of these have been replaced with alternatives that can not be manipulated or fooled that easily. PR-URL: https://github.com/nodejs/node/pull/24831 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/internal/util/comparisons.js51
1 files changed, 38 insertions, 13 deletions
diff --git a/lib/internal/util/comparisons.js b/lib/internal/util/comparisons.js
index 905946fdee..1d959f843b 100644
--- a/lib/internal/util/comparisons.js
+++ b/lib/internal/util/comparisons.js
@@ -7,7 +7,14 @@ const {
isDate,
isMap,
isRegExp,
- isSet
+ isSet,
+ isNativeError,
+ isBoxedPrimitive,
+ isNumberObject,
+ isStringObject,
+ isBooleanObject,
+ isBigIntObject,
+ isSymbolObject
} = internalBinding('types');
const {
getOwnNonIndexProperties,
@@ -33,6 +40,13 @@ const kIsMap = 3;
const objectToString = uncurryThis(Object.prototype.toString);
const hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
const propertyIsEnumerable = uncurryThis(Object.prototype.propertyIsEnumerable);
+const dateGetTime = uncurryThis(Date.prototype.getTime);
+
+const bigIntValueOf = uncurryThis(BigInt.prototype.valueOf);
+const booleanValueOf = uncurryThis(Boolean.prototype.valueOf);
+const numberValueOf = uncurryThis(Number.prototype.valueOf);
+const symbolValueOf = uncurryThis(Symbol.prototype.valueOf);
+const stringValueOf = uncurryThis(String.prototype.valueOf);
const objectKeys = Object.keys;
const getPrototypeOf = Object.getPrototypeOf;
@@ -82,6 +96,24 @@ function isObjectOrArrayTag(tag) {
return tag === '[object Array]' || tag === '[object Object]';
}
+function isEqualBoxedPrimitive(val1, val2) {
+ if (isNumberObject(val1)) {
+ return isNumberObject(val2) &&
+ objectIs(numberValueOf(val1), numberValueOf(val2));
+ }
+ if (isStringObject(val1)) {
+ return isStringObject(val2) && stringValueOf(val1) === stringValueOf(val2);
+ }
+ if (isBooleanObject(val1)) {
+ return isBooleanObject(val2) &&
+ booleanValueOf(val1) === booleanValueOf(val2);
+ }
+ if (isBigIntObject(val1)) {
+ return isBigIntObject(val2) && bigIntValueOf(val1) === bigIntValueOf(val2);
+ }
+ return isSymbolObject(val2) && symbolValueOf(val1) === symbolValueOf(val2);
+}
+
// Notes: Type tags are historical [[Class]] properties that can be set by
// FunctionTemplate::SetClassName() in C++ or Symbol.toStringTag in JS
// and retrieved using Object.prototype.toString.call(obj) in JS
@@ -117,7 +149,7 @@ function strictDeepEqual(val1, val2, memos) {
if (getPrototypeOf(val1) !== getPrototypeOf(val2)) {
return false;
}
- if (val1Tag === '[object Array]') {
+ if (Array.isArray(val1)) {
// Check for sparse arrays and general fast path
if (val1.length !== val2.length) {
return false;
@@ -133,15 +165,14 @@ function strictDeepEqual(val1, val2, memos) {
return keyCheck(val1, val2, kStrict, memos, kNoIterator);
}
if (isDate(val1)) {
- // TODO: Make these safe.
- if (val1.getTime() !== val2.getTime()) {
+ if (dateGetTime(val1) !== dateGetTime(val2)) {
return false;
}
} else if (isRegExp(val1)) {
if (!areSimilarRegExps(val1, val2)) {
return false;
}
- } else if (val1Tag === '[object Error]') {
+ } else if (isNativeError(val1) || val1 instanceof Error) {
// Do not compare the stack as it might differ even though the error itself
// is otherwise identical. The non-enumerable name should be identical as
// the prototype is also identical. Otherwise this is caught later on.
@@ -175,14 +206,8 @@ function strictDeepEqual(val1, val2, memos) {
if (!areEqualArrayBuffers(val1, val2)) {
return false;
}
- // TODO: Make the valueOf checks safe.
- } else if (typeof val1.valueOf === 'function') {
- const val1Value = val1.valueOf();
- if (val1Value !== val1 &&
- (typeof val2.valueOf !== 'function' ||
- !innerDeepEqual(val1Value, val2.valueOf(), kStrict))) {
- return false;
- }
+ } else if (isBoxedPrimitive(val1) && !isEqualBoxedPrimitive(val1, val2)) {
+ return false;
}
return keyCheck(val1, val2, kStrict, memos, kNoIterator);
}