From 2abf0afb2b9e2f9e9824e2cbb08bdec27794d039 Mon Sep 17 00:00:00 2001 From: Denys Otrishko Date: Thu, 23 Jan 2020 20:55:53 +0200 Subject: [PATCH] vm: refactor value validation with internal/validators.js PR-URL: https://github.com/nodejs/node/pull/31480 Reviewed-By: James M Snell Reviewed-By: Gus Caplan --- lib/vm.js | 126 +++++++++++++++++------------------------------------- 1 file changed, 40 insertions(+), 86 deletions(-) diff --git a/lib/vm.js b/lib/vm.js index 211755b9728566..1d0715af528c73 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -22,7 +22,6 @@ 'use strict'; const { - ArrayIsArray, ArrayPrototypeForEach, Symbol, } = primordials; @@ -42,7 +41,11 @@ const { const { validateInt32, validateUint32, - validateString + validateString, + validateArray, + validateBoolean, + validateBuffer, + validateObject, } = require('internal/validators'); const { kVmBreakFirstLineSymbol } = require('internal/util'); const kParsingContext = Symbol('script parsing context'); @@ -139,30 +142,14 @@ class Script extends ContextifyScript { } function validateContext(contextifiedObject) { - if (typeof contextifiedObject !== 'object' || contextifiedObject === null) { - throw new ERR_INVALID_ARG_TYPE('contextifiedObject', 'Object', - contextifiedObject); - } - if (!_isContext(contextifiedObject)) { + if (!isContext(contextifiedObject)) { throw new ERR_INVALID_ARG_TYPE('contextifiedObject', 'vm.Context', contextifiedObject); } } -function validateBool(prop, propName) { - if (prop !== undefined && typeof prop !== 'boolean') - throw new ERR_INVALID_ARG_TYPE(propName, 'boolean', prop); -} - -function validateObject(prop, propName) { - if (prop !== undefined && (typeof prop !== 'object' || prop === null)) - throw new ERR_INVALID_ARG_TYPE(propName, 'Object', prop); -} - function getRunInContextArgs(options = {}) { - if (typeof options !== 'object' || options === null) { - throw new ERR_INVALID_ARG_TYPE('options', 'Object', options); - } + validateObject(options, 'options'); let timeout = options.timeout; if (timeout === undefined) { @@ -177,14 +164,8 @@ function getRunInContextArgs(options = {}) { [kVmBreakFirstLineSymbol]: breakFirstLine = false, } = options; - if (typeof displayErrors !== 'boolean') { - throw new ERR_INVALID_ARG_TYPE('options.displayErrors', 'boolean', - displayErrors); - } - if (typeof breakOnSigint !== 'boolean') { - throw new ERR_INVALID_ARG_TYPE('options.breakOnSigint', 'boolean', - breakOnSigint); - } + validateBoolean(displayErrors, 'options.displayErrors'); + validateBoolean(breakOnSigint, 'options.breakOnSigint'); return { breakOnSigint, @@ -193,30 +174,28 @@ function getRunInContextArgs(options = {}) { } function getContextOptions(options) { - if (options) { + if (!options) + return {}; + const contextOptions = { + name: options.contextName, + origin: options.contextOrigin, + codeGeneration: undefined, + }; + if (contextOptions.name !== undefined) + validateString(contextOptions.name, 'options.contextName'); + if (contextOptions.origin !== undefined) + validateString(contextOptions.origin, 'options.contextOrigin'); + if (options.contextCodeGeneration !== undefined) { validateObject(options.contextCodeGeneration, 'options.contextCodeGeneration'); - const contextOptions = { - name: options.contextName, - origin: options.contextOrigin, - codeGeneration: typeof options.contextCodeGeneration === 'object' ? { - strings: options.contextCodeGeneration.strings, - wasm: options.contextCodeGeneration.wasm, - } : undefined, - }; - if (contextOptions.name !== undefined) - validateString(contextOptions.name, 'options.contextName'); - if (contextOptions.origin !== undefined) - validateString(contextOptions.origin, 'options.contextOrigin'); - if (contextOptions.codeGeneration) { - validateBool(contextOptions.codeGeneration.strings, - 'options.contextCodeGeneration.strings'); - validateBool(contextOptions.codeGeneration.wasm, - 'options.contextCodeGeneration.wasm'); - } - return contextOptions; + const { strings, wasm } = options.contextCodeGeneration; + if (strings !== undefined) + validateBoolean(strings, 'options.contextCodeGeneration.strings'); + if (wasm !== undefined) + validateBoolean(wasm, 'options.contextCodeGeneration.wasm'); + contextOptions.codeGeneration = { strings, wasm }; } - return {}; + return contextOptions; } function isContext(object) { @@ -232,9 +211,7 @@ function createContext(contextObject = {}, options = {}) { return contextObject; } - if (typeof options !== 'object' || options === null) { - throw new ERR_INVALID_ARG_TYPE('options', 'Object', options); - } + validateObject(options, 'options'); const { name = `VM Context ${defaultContextNameIndex++}`, @@ -245,14 +222,15 @@ function createContext(contextObject = {}, options = {}) { validateString(name, 'options.name'); if (origin !== undefined) validateString(origin, 'options.origin'); - validateObject(codeGeneration, 'options.codeGeneration'); + if (codeGeneration !== undefined) + validateObject(codeGeneration, 'options.codeGeneration'); let strings = true; let wasm = true; if (codeGeneration !== undefined) { ({ strings = true, wasm = true } = codeGeneration); - validateBool(strings, 'options.codeGeneration.strings'); - validateBool(wasm, 'options.codeGeneration.wasm'); + validateBoolean(strings, 'options.codeGeneration.strings'); + validateBoolean(wasm, 'options.codeGeneration.wasm'); } makeContext(contextObject, name, origin, strings, wasm); @@ -314,9 +292,7 @@ function runInThisContext(code, options) { function compileFunction(code, params, options = {}) { validateString(code, 'code'); if (params !== undefined) { - if (!ArrayIsArray(params)) { - throw new ERR_INVALID_ARG_TYPE('params', 'Array', params); - } + validateArray(params, 'params'); ArrayPrototypeForEach(params, (param, i) => validateString(param, `params[${i}]`)); } @@ -334,20 +310,9 @@ function compileFunction(code, params, options = {}) { validateString(filename, 'options.filename'); validateUint32(columnOffset, 'options.columnOffset'); validateUint32(lineOffset, 'options.lineOffset'); - if (cachedData !== undefined && !isArrayBufferView(cachedData)) { - throw new ERR_INVALID_ARG_TYPE( - 'options.cachedData', - ['Buffer', 'TypedArray', 'DataView'], - cachedData - ); - } - if (typeof produceCachedData !== 'boolean') { - throw new ERR_INVALID_ARG_TYPE( - 'options.produceCachedData', - 'boolean', - produceCachedData - ); - } + if (cachedData !== undefined) + validateBuffer(cachedData, 'options.cachedData'); + validateBoolean(produceCachedData, 'options.produceCachedData'); if (parsingContext !== undefined) { if ( typeof parsingContext !== 'object' || @@ -361,21 +326,10 @@ function compileFunction(code, params, options = {}) { ); } } - if (!ArrayIsArray(contextExtensions)) { - throw new ERR_INVALID_ARG_TYPE( - 'options.contextExtensions', - 'Array', - contextExtensions - ); - } + validateArray(contextExtensions, 'options.contextExtensions'); ArrayPrototypeForEach(contextExtensions, (extension, i) => { - if (typeof extension !== 'object') { - throw new ERR_INVALID_ARG_TYPE( - `options.contextExtensions[${i}]`, - 'object', - extension - ); - } + const name = `options.contextExtensions[${i}]`; + validateObject(extension, name, { nullable: true }); }); const result = _compileFunction(