From 2d07b3e6d7a1206bc103002b65abfbe1344a171e Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Sun, 22 Jun 2025 11:59:16 -0700 Subject: [PATCH] Removed protections against user code redefining undefined Jasmine hasn't even run on platforms that allowed redefining undefined since 2.x. --- lib/jasmine-core/jasmine.js | 43 +++++++++--------------- spec/core/UtilSpec.js | 11 ------ src/core/ClearStack.js | 7 ++-- src/core/MockDate.js | 2 +- src/core/PrettyPrinter.js | 2 +- src/core/SpyRegistry.js | 12 +++---- src/core/asymmetric_equality/Anything.js | 2 +- src/core/base.js | 4 +-- src/core/matchers/DiffBuilder.js | 6 ++-- src/core/matchers/matchersUtil.js | 4 +-- src/core/util.js | 4 --- 11 files changed, 32 insertions(+), 65 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 4a453115..0c877785 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -253,9 +253,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { }; j$.isObject_ = function(value) { - return ( - !j$.util.isUndefined(value) && value !== null && j$.isA_('Object', value) - ); + return value !== undefined && value !== null && j$.isA_('Object', value); }; j$.isString_ = function(value) { @@ -676,10 +674,6 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { getJasmineRequireObj().util = function(j$) { const util = {}; - util.isUndefined = function(obj) { - return obj === void 0; - }; - util.clone = function(obj) { if (Object.prototype.toString.apply(obj) === '[object Array]') { return obj.slice(); @@ -2315,7 +2309,7 @@ getJasmineRequireObj().Anything = function(j$) { function Anything() {} Anything.prototype.asymmetricMatch = function(other) { - return !j$.util.isUndefined(other) && other !== null; + return other !== undefined && other !== null; }; Anything.prototype.jasmineToString = function() { @@ -2976,7 +2970,7 @@ getJasmineRequireObj().clearStack = function(j$) { function getUnclampedSetTimeout(global) { const { setTimeout } = global; - if (j$.util.isUndefined(global.MessageChannel)) { + if (!global.MessageChannel) { return setTimeout; } @@ -3036,10 +3030,7 @@ getJasmineRequireObj().clearStack = function(j$) { // Unlike browsers, Node doesn't require us to do a periodic setTimeout // so we avoid the overhead. return nodeQueueMicrotaskImpl(global); - } else if ( - SAFARI_OR_WIN_WEBKIT || - j$.util.isUndefined(global.MessageChannel) /* tests */ - ) { + } else if (SAFARI_OR_WIN_WEBKIT || !global.MessageChannel /* tests */) { // queueMicrotask is dramatically faster than MessageChannel in Safari // and other WebKit-based browsers, such as the one distributed by Playwright // to test Safari-like behavior on Windows. @@ -4877,10 +4868,8 @@ getJasmineRequireObj().DiffBuilder = function(j$) { const actualCustom = this.prettyPrinter_.customFormat_(actual); const expectedCustom = this.prettyPrinter_.customFormat_(expected); - const useCustom = !( - j$.util.isUndefined(actualCustom) && - j$.util.isUndefined(expectedCustom) - ); + const useCustom = + actualCustom !== undefined || expectedCustom !== undefined; if (useCustom) { const prettyActual = actualCustom || this.prettyPrinter_(actual); @@ -5139,13 +5128,13 @@ getJasmineRequireObj().MatchersUtil = function(j$) { bStack, diffBuilder ); - if (!j$.util.isUndefined(asymmetricResult)) { + if (asymmetricResult !== undefined) { return asymmetricResult; } for (const tester of this.customTesters_) { const customTesterResult = tester(a, b); - if (!j$.util.isUndefined(customTesterResult)) { + if (customTesterResult !== undefined) { if (!customTesterResult) { diffBuilder.recordMismatch(); } @@ -7527,7 +7516,7 @@ getJasmineRequireObj().MockDate = function(j$) { if (mockDate instanceof GlobalDate) { currentTime = mockDate.getTime(); } else { - if (!j$.util.isUndefined(mockDate)) { + if (mockDate !== undefined) { throw new Error( 'The argument to jasmine.clock().mockDate(), if specified, ' + 'should be a Date instance.' @@ -7744,7 +7733,7 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) { if (customFormatResult) { this.emitScalar(customFormatResult); - } else if (j$.util.isUndefined(value)) { + } else if (value === undefined) { this.emitScalar('undefined'); } else if (value === null) { this.emitScalar('null'); @@ -9843,7 +9832,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) { this.spyOn = function(obj, methodName) { const getErrorMsg = spyOnMsg; - if (j$.util.isUndefined(obj) || obj === null) { + if (obj === undefined || obj === null) { throw new Error( getErrorMsg( 'could not find an object to spy upon for ' + methodName + '()' @@ -9851,11 +9840,11 @@ getJasmineRequireObj().SpyRegistry = function(j$) { ); } - if (j$.util.isUndefined(methodName) || methodName === null) { + if (methodName === undefined || methodName === null) { throw new Error(getErrorMsg('No method name supplied')); } - if (j$.util.isUndefined(obj[methodName])) { + if (obj[methodName] === undefined) { throw new Error(getErrorMsg(methodName + '() method does not exist')); } @@ -9920,7 +9909,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) { accessType = accessType || 'get'; - if (j$.util.isUndefined(obj)) { + if (!obj) { throw new Error( getErrorMsg( 'spyOn could not find an object to spy upon for ' + @@ -9930,7 +9919,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) { ); } - if (j$.util.isUndefined(propertyName)) { + if (propertyName === undefined) { throw new Error(getErrorMsg('No property name supplied')); } @@ -9995,7 +9984,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) { }; this.spyOnAllFunctions = function(obj, includeNonEnumerable) { - if (j$.util.isUndefined(obj)) { + if (!obj) { throw new Error( 'spyOnAllFunctions could not find an object to spy upon' ); diff --git a/spec/core/UtilSpec.js b/spec/core/UtilSpec.js index 3374479d..5ec6b36b 100644 --- a/spec/core/UtilSpec.js +++ b/spec/core/UtilSpec.js @@ -128,17 +128,6 @@ describe('util', function() { }); }); - describe('isUndefined', function() { - it('reports if a variable is defined', function() { - let a; - expect(jasmineUnderTest.util.isUndefined(a)).toBe(true); - expect(jasmineUnderTest.util.isUndefined(undefined)).toBe(true); - - const defined = 'diz be undefined yo'; - expect(jasmineUnderTest.util.isUndefined(defined)).toBe(false); - }); - }); - describe('cloneArgs', function() { it('clones primitives as-is', function() { expect(jasmineUnderTest.util.cloneArgs([true, false])).toEqual([ diff --git a/src/core/ClearStack.js b/src/core/ClearStack.js index 5b239f0e..c2948cff 100644 --- a/src/core/ClearStack.js +++ b/src/core/ClearStack.js @@ -44,7 +44,7 @@ getJasmineRequireObj().clearStack = function(j$) { function getUnclampedSetTimeout(global) { const { setTimeout } = global; - if (j$.util.isUndefined(global.MessageChannel)) { + if (!global.MessageChannel) { return setTimeout; } @@ -104,10 +104,7 @@ getJasmineRequireObj().clearStack = function(j$) { // Unlike browsers, Node doesn't require us to do a periodic setTimeout // so we avoid the overhead. return nodeQueueMicrotaskImpl(global); - } else if ( - SAFARI_OR_WIN_WEBKIT || - j$.util.isUndefined(global.MessageChannel) /* tests */ - ) { + } else if (SAFARI_OR_WIN_WEBKIT || !global.MessageChannel /* tests */) { // queueMicrotask is dramatically faster than MessageChannel in Safari // and other WebKit-based browsers, such as the one distributed by Playwright // to test Safari-like behavior on Windows. diff --git a/src/core/MockDate.js b/src/core/MockDate.js index 3ddb68ad..d73c8ba9 100644 --- a/src/core/MockDate.js +++ b/src/core/MockDate.js @@ -15,7 +15,7 @@ getJasmineRequireObj().MockDate = function(j$) { if (mockDate instanceof GlobalDate) { currentTime = mockDate.getTime(); } else { - if (!j$.util.isUndefined(mockDate)) { + if (mockDate !== undefined) { throw new Error( 'The argument to jasmine.clock().mockDate(), if specified, ' + 'should be a Date instance.' diff --git a/src/core/PrettyPrinter.js b/src/core/PrettyPrinter.js index 7ea2ffd8..5489f910 100644 --- a/src/core/PrettyPrinter.js +++ b/src/core/PrettyPrinter.js @@ -16,7 +16,7 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) { if (customFormatResult) { this.emitScalar(customFormatResult); - } else if (j$.util.isUndefined(value)) { + } else if (value === undefined) { this.emitScalar('undefined'); } else if (value === null) { this.emitScalar('null'); diff --git a/src/core/SpyRegistry.js b/src/core/SpyRegistry.js index fece1b44..7042388b 100644 --- a/src/core/SpyRegistry.js +++ b/src/core/SpyRegistry.js @@ -25,7 +25,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) { this.spyOn = function(obj, methodName) { const getErrorMsg = spyOnMsg; - if (j$.util.isUndefined(obj) || obj === null) { + if (obj === undefined || obj === null) { throw new Error( getErrorMsg( 'could not find an object to spy upon for ' + methodName + '()' @@ -33,11 +33,11 @@ getJasmineRequireObj().SpyRegistry = function(j$) { ); } - if (j$.util.isUndefined(methodName) || methodName === null) { + if (methodName === undefined || methodName === null) { throw new Error(getErrorMsg('No method name supplied')); } - if (j$.util.isUndefined(obj[methodName])) { + if (obj[methodName] === undefined) { throw new Error(getErrorMsg(methodName + '() method does not exist')); } @@ -102,7 +102,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) { accessType = accessType || 'get'; - if (j$.util.isUndefined(obj)) { + if (!obj) { throw new Error( getErrorMsg( 'spyOn could not find an object to spy upon for ' + @@ -112,7 +112,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) { ); } - if (j$.util.isUndefined(propertyName)) { + if (propertyName === undefined) { throw new Error(getErrorMsg('No property name supplied')); } @@ -177,7 +177,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) { }; this.spyOnAllFunctions = function(obj, includeNonEnumerable) { - if (j$.util.isUndefined(obj)) { + if (!obj) { throw new Error( 'spyOnAllFunctions could not find an object to spy upon' ); diff --git a/src/core/asymmetric_equality/Anything.js b/src/core/asymmetric_equality/Anything.js index ce436cb4..b22189b5 100644 --- a/src/core/asymmetric_equality/Anything.js +++ b/src/core/asymmetric_equality/Anything.js @@ -2,7 +2,7 @@ getJasmineRequireObj().Anything = function(j$) { function Anything() {} Anything.prototype.asymmetricMatch = function(other) { - return !j$.util.isUndefined(other) && other !== null; + return other !== undefined && other !== null; }; Anything.prototype.jasmineToString = function() { diff --git a/src/core/base.js b/src/core/base.js index a25241d7..95ea4bba 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -73,9 +73,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { }; j$.isObject_ = function(value) { - return ( - !j$.util.isUndefined(value) && value !== null && j$.isA_('Object', value) - ); + return value !== undefined && value !== null && j$.isA_('Object', value); }; j$.isString_ = function(value) { diff --git a/src/core/matchers/DiffBuilder.js b/src/core/matchers/DiffBuilder.js index b68a91f4..3aed1916 100644 --- a/src/core/matchers/DiffBuilder.js +++ b/src/core/matchers/DiffBuilder.js @@ -31,10 +31,8 @@ getJasmineRequireObj().DiffBuilder = function(j$) { const actualCustom = this.prettyPrinter_.customFormat_(actual); const expectedCustom = this.prettyPrinter_.customFormat_(expected); - const useCustom = !( - j$.util.isUndefined(actualCustom) && - j$.util.isUndefined(expectedCustom) - ); + const useCustom = + actualCustom !== undefined || expectedCustom !== undefined; if (useCustom) { const prettyActual = actualCustom || this.prettyPrinter_(actual); diff --git a/src/core/matchers/matchersUtil.js b/src/core/matchers/matchersUtil.js index cf265b26..58f035c2 100644 --- a/src/core/matchers/matchersUtil.js +++ b/src/core/matchers/matchersUtil.js @@ -177,13 +177,13 @@ getJasmineRequireObj().MatchersUtil = function(j$) { bStack, diffBuilder ); - if (!j$.util.isUndefined(asymmetricResult)) { + if (asymmetricResult !== undefined) { return asymmetricResult; } for (const tester of this.customTesters_) { const customTesterResult = tester(a, b); - if (!j$.util.isUndefined(customTesterResult)) { + if (customTesterResult !== undefined) { if (!customTesterResult) { diffBuilder.recordMismatch(); } diff --git a/src/core/util.js b/src/core/util.js index 210ce121..45bf2d62 100644 --- a/src/core/util.js +++ b/src/core/util.js @@ -1,10 +1,6 @@ getJasmineRequireObj().util = function(j$) { const util = {}; - util.isUndefined = function(obj) { - return obj === void 0; - }; - util.clone = function(obj) { if (Object.prototype.toString.apply(obj) === '[object Array]') { return obj.slice();