From 18e01c45590a4ec90465621fe3a6b291ec3e318e Mon Sep 17 00:00:00 2001 From: overlookmotel Date: Thu, 23 Nov 2023 11:39:20 +0000 Subject: [PATCH] Tests WIP 1 --- test/eval.test.js | 261 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) diff --git a/test/eval.test.js b/test/eval.test.js index ac28a27b..e85de993 100644 --- a/test/eval.test.js +++ b/test/eval.test.js @@ -1717,6 +1717,214 @@ describe('eval', () => { }); }); + describe('does not freeze vars internal to function where not accessible to eval', () => { + describe('in nested blocks', () => { + itSerializes('where vars differently named from frozen vars', { + in: ` + module.exports = function(module, exports) { + const intA = 1; + { + let intB; + intB = 2; + { + let intC = 3; + } + } + return eval('intA'); + }; + `, + out: `(0,eval)(" + (function(module,exports){const intA=1;{let a;a=2;{let b=3}}return eval(\\"intA\\")}) + ")`, + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toBe(1); + } + }); + + itSerializes('where var shares name with frozen var', { + in: ` + module.exports = function(module, exports) { + const intA = 1; + { + let intA; + intA = 2; + { + let intC = 3; + } + } + return eval('intA'); + }; + `, + out: `(0,eval)(" + (function(module,exports){const intA=1;{let a;a=2;{let b=3}}return eval(\\"intA\\")}) + ")`, + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toBe(1); + } + }); + }); + + describe('in nested functions', () => { + itSerializes('where vars differently named from frozen vars', { + in: ` + module.exports = function(module, exports) { + const intA = 1, intB = 2; + return [ + ...eval('[intA, intB]'), + ...(intC => { let intD = 4; return [intC, intD]; })(3) + ]; + }; + `, + out: `(0,eval)(" + (function(module,exports){ + const intA=1,intB=2; + return[...eval(\\"[intA, intB]\\"),...(a=>{let b=4;return[a,b]})(3)] + }) + ")`, + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toEqual([1, 2, 3, 4]); + } + }); + + itSerializes('where vars share names with frozen vars', { + in: ` + module.exports = function(module, exports) { + const intA = 1, intB = 2; + return [ + ...eval('[intA, intB]'), + ...(intA => { let intB = 4; return [intA, intB]; })(3) + ]; + }; + `, + out: `(0,eval)(" + (function(module,exports){ + const intA=1,intB=2; + return[...eval(\\"[intA, intB]\\"),...(a=>{let b=4;return[a,b]})(3)] + }) + ")`, + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toEqual([1, 2, 3, 4]); + } + }); + }); + + describe('in function body where eval in function params', () => { + itSerializes('where vars differently named from frozen vars', { + in: ` + module.exports = function(intA = 1, intB = eval('intA'), module, exports) { + const intC = 2; + { + const intD = 3; + return [intA, intB, intC, intD]; + } + }; + `, + out: `(0,eval)(" + (function(intA=1,intB=eval(\\"intA\\"),module,exports){ + const a=2; + { + const b=3; + return[intA,intB,a,b] + } + }) + ")`, + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toEqual([1, 1, 2, 3]); + } + }); + + itSerializes('where vars share names with frozen vars', { + in: ` + module.exports = function(intA = 1, intB = eval('intA'), module, exports) { + const out = [intA, intB]; + { + const intA = 2, intB = 3; + return [...out, intA, intB]; + } + }; + `, + out: `(0,eval)(" + (function(intA=1,intB=eval(\\"intA\\"),module,exports){ + const a=[intA,intB]; + { + const b=2,c=3; + return[...a,b,c] + } + }) + ")`, + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toEqual([1, 1, 2, 3]); + } + }); + }); + + describe('where eval in nested function', () => { + itSerializes('where vars differently named from frozen vars', { + in: ` + module.exports = function(module, exports) { + const intA = 1, intB = 2; + const fn = () => eval('[intA, intB]'); + { + const intC = 3; + const intD = (intE => intE)(4); + return [intA, intB, ...fn(), intC, intD]; + } + }; + `, + out: `(0,eval)(" + (function(module,exports){ + const intA=1,intB=2; + const fn=()=>eval(\\"[intA, intB]\\"); + { + const a=3; + const b=(c=>c)(4); + return[intA,intB,...fn(),a,b] + } + }) + ")`, + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toEqual([1, 2, 1, 2, 3, 4]); + } + }); + + itSerializes('where vars share names with frozen vars', { + in: ` + module.exports = function(module, exports) { + const intA = 1, intB = 2, intC = 3; + const fn = () => eval('[intA, intB, intC]'); + { + const intA = 4; + const intB = (intC => intC)(5); + return [...fn(), intA, intB]; + } + }; + `, + out: `(0,eval)(" + (function(module,exports){ + const intA=1,intB=2,intC=3; + const fn=()=>eval(\\"[intA, intB, intC]\\"); + { + const a=4; + const b=(c=>c)(5); + return[...fn(),a,b] + } + }) + ")`, + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toEqual([1, 2, 3, 4, 5]); + } + }); + }); + }); + describe('prevents shadowed vars in upper scopes being accessible to eval', () => { itSerializes('simple case', { in: ` @@ -1829,6 +2037,59 @@ describe('eval', () => { expect(evalFn()).toEqual({extA: 1, extB: 10, extC: 3, typeofA: 'undefined'}); } }); + + describe('where shadowed var internal to function', () => { + itSerializes('simple case', { + in: ` + module.exports = function(module, exports) { + const intA = 1, intB = intA; + { + const intA = 2; + return eval('({intA, intB, typeofA: typeof a})'); + } + }; + `, + out: `(0,eval)(" + (function(module,exports){ + const intA=1,intB=intA; + { + const intA=2; + return eval(\\"({intA, intB, typeofA: typeof a})\\") + } + }) + ")`, + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toEqual({intA: 2, intB: 1, typeofA: 'undefined'}); + } + }); + + itSerializes('where var is not accessible to eval due to strict mode rules', { + // `package` is a reserved keyword in strict mode + in: ` + module.exports = function(module, exports) { + const package = 1, intA = package; + return (() => { + 'use strict'; + return eval('({intA, typeofA: typeof a})') + })(); + }; + `, + out: `(0,eval)(" + (function(module,exports){ + const package=1,intA=package; + return(()=>{ + \\"use strict\\"; + return eval(\\"({intA, typeofA: typeof a})\\") + })() + }) + ")`, + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toEqual({intA: 1, typeofA: 'undefined'}); + } + }); + }); }); describe('prevents Livepack external vars blocking access to globals in eval', () => {