diff --git a/src/checker/common/full-callgraph-file-entrypoint.ts b/src/checker/common/full-callgraph-file-entrypoint.ts index 5b40902b..9cd375d3 100644 --- a/src/checker/common/full-callgraph-file-entrypoint.ts +++ b/src/checker/common/full-callgraph-file-entrypoint.ts @@ -153,7 +153,7 @@ function makeFullCallGraph(analyzer: any): void { funcSymbolAny2.fdef.type === 'FunctionDefinition' ) { alreadyCheckList.push(funcSymbolAny2) - const argValues: any[] = [] + const argValues: Record = [] analyzer.executeCall( funcSymbolAny2.fdef, funcSymbolAny2, diff --git a/src/checker/common/ql-uast-convert/converter.ts b/src/checker/common/ql-uast-convert/converter.ts index 42bb445c..418d6184 100644 --- a/src/checker/common/ql-uast-convert/converter.ts +++ b/src/checker/common/ql-uast-convert/converter.ts @@ -295,9 +295,9 @@ function calcEntryPointAndRun(options: any, fileManager: any, analyzer: any): vo entryPoints.forEach((main: any) => { const nd = AstUtilConverter.satisfy(main.ast, (n: any) => n?._meta?.isSource === true) if (nd) { - const argValues: any[] = [] + const argValues: Record = [] for (const key in main?.ast?.parameters) { - argValues.push(analyzer.processInstruction(filescope, main.ast.parameters[key], state)) + argValues[key] = analyzer.processInstruction(filescope, main.ast.parameters[key], state) } logger.info(`entryPoint ${main?.ast?.loc?.sourcefile}:${main.id}`) analyzer.executeCall(main.ast, main, argValues, state, filescope) diff --git a/src/checker/common/rules-basic-handler.ts b/src/checker/common/rules-basic-handler.ts index 86d3d69c..11b44ba3 100644 --- a/src/checker/common/rules-basic-handler.ts +++ b/src/checker/common/rules-basic-handler.ts @@ -47,9 +47,9 @@ function getRules(ruleConfigPath: string): any[] { * @param fclos * @param rule */ -function prepareArgs(argvalues: any[], fclos: any, rule: Rule): any[] { +function prepareArgs(argvalues: Record, fclos: any, rule: Rule): any[] { let { args } = rule - let res = argvalues.concat() + let res = Object.values(argvalues).concat() args = (args || []).map((item: string | number) => { if (item !== '*') { return parseInt(String(item)) @@ -58,7 +58,7 @@ function prepareArgs(argvalues: any[], fclos: any, rule: Rule): any[] { }) if (!args.some((v: string | number) => v === '*')) { args = args.filter((v: string | number) => typeof v === 'number') - res = argvalues.filter((value: any, index: number) => { + res = Object.values(argvalues).filter((value: any, index: number) => { return (args as number[]).indexOf(index) !== -1 }) } diff --git a/src/checker/sanitizer/sanitizer-checker.ts b/src/checker/sanitizer/sanitizer-checker.ts index 226f446a..16f18230 100644 --- a/src/checker/sanitizer/sanitizer-checker.ts +++ b/src/checker/sanitizer/sanitizer-checker.ts @@ -149,7 +149,7 @@ class SanitizerChecker extends Checker { node: any, fclos: any, ret: any, - argvalues: any[], + argvalues: Record, scope: any, callstack: any ): void { diff --git a/src/checker/taint/common-kit/sink-util.ts b/src/checker/taint/common-kit/sink-util.ts index 98a80b22..5aaf8a5a 100644 --- a/src/checker/taint/common-kit/sink-util.ts +++ b/src/checker/taint/common-kit/sink-util.ts @@ -19,12 +19,22 @@ interface SinkRule { * @param argvalues * @returns {Array} */ -function matchSinkAtFuncCall(node: any, fclos: any, sinks: SinkRule[], argvalues: any[]): SinkRule[] { +function matchSinkAtFuncCall( + node: any, + fclos: any, + sinks: SinkRule[], + argvalues: Record +): SinkRule[] { const callExpr = node.callee || node const res: SinkRule[] = [] if (sinks && sinks.length > 0) { for (const tspec of sinks) { - if (tspec.argNum !== undefined && tspec.argNum >= 0 && argvalues && tspec.argNum !== argvalues.length) { + if ( + tspec.argNum !== undefined && + tspec.argNum >= 0 && + argvalues && + tspec.argNum !== Object.keys(argvalues).length + ) { continue } @@ -56,7 +66,7 @@ function matchSinkAtFuncCallWithCalleeType( fclos: any, rules: SinkRule[], scope: any, - argvalues: any[] + argvalues: Record ): SinkRule[] { const callExpr = node.callee || node const res: SinkRule[] = [] @@ -68,7 +78,12 @@ function matchSinkAtFuncCallWithCalleeType( return res } for (const tspec of rules) { - if (tspec.argNum !== undefined && tspec.argNum >= 0 && argvalues && tspec.argNum !== argvalues.length) { + if ( + tspec.argNum !== undefined && + tspec.argNum >= 0 && + argvalues && + tspec.argNum !== Object.keys(argvalues).length + ) { continue } diff --git a/src/checker/taint/go/gRpc-entrypoint-collect-checker.ts b/src/checker/taint/go/gRpc-entrypoint-collect-checker.ts index d42024a1..2c858a98 100644 --- a/src/checker/taint/go/gRpc-entrypoint-collect-checker.ts +++ b/src/checker/taint/go/gRpc-entrypoint-collect-checker.ts @@ -114,7 +114,7 @@ class GRpcEntrypointCollectChecker extends Checker { const { fclos, argvalues } = info if (config.entryPointMode === 'ONLY_CUSTOM') return // 不路由自采集 if (!(fclos._qid in registerServerPoints)) return // 处理Register_xxx_Server函数,即实现类注册点 - if (!Array.isArray(argvalues) || argvalues.length < 1) return + if (!Array.isArray(argvalues) || Object.keys(argvalues).length < 1) return const serverName = registerServerPoints[fclos._qid] const implServer = argvalues[1] this.searchServiceEntryPoints(serverName, implServer, fclos, state, analyzer) diff --git a/src/checker/taint/go/gin-default-taint-checker.ts b/src/checker/taint/go/gin-default-taint-checker.ts index 330af726..830056d4 100644 --- a/src/checker/taint/go/gin-default-taint-checker.ts +++ b/src/checker/taint/go/gin-default-taint-checker.ts @@ -227,7 +227,7 @@ class GinDefaultTaintChecker extends TaintChecker { !callExpNode.loc || !calleeObject || !argValues || - argValues.length <= 0 + Object.keys(argValues).length <= 0 ) return null const routeFCloses = GinEntryPoint.collectRouteRegistry(callExpNode, calleeObject, argValues, scope) diff --git a/src/checker/taint/go/gin-taint-checker.ts b/src/checker/taint/go/gin-taint-checker.ts index 2b7982c5..43c3cf6c 100644 --- a/src/checker/taint/go/gin-taint-checker.ts +++ b/src/checker/taint/go/gin-taint-checker.ts @@ -223,7 +223,7 @@ class GinTaintChecker extends TaintChecker { !callExpNode.loc || !calleeObject || !argValues || - argValues.length <= 0 + Object.keys(argValues).length <= 0 ) return null const routeFCloses = GinEntryPoint.collectRouteRegistry(callExpNode, calleeObject, argValues, scope) diff --git a/src/checker/taint/go/sync-once-do-checker.ts b/src/checker/taint/go/sync-once-do-checker.ts index 654dad57..bcfcc168 100644 --- a/src/checker/taint/go/sync-once-do-checker.ts +++ b/src/checker/taint/go/sync-once-do-checker.ts @@ -5,7 +5,7 @@ const syncOnceDoQid: string = 'sync.Once.Do' interface TriggerInfo { fclos: any - argvalues: any[] + argvalues: Record [key: string]: any } @@ -36,7 +36,7 @@ class syncOnceDoChecker extends CheckerSyncOnceDo { const hash: string = JSON.stringify(node.loc) if (done.has(hash)) return done.add(hash) - if (argvalues.length !== 1 && argvalues[0].vtype !== 'fclos') return + if (Object.keys(argvalues).length !== 1 && argvalues[0].vtype !== 'fclos') return const fDef = node.arguments[0] const fClos = argvalues[0] diff --git a/src/engine/analyzer/common/analyzer.ts b/src/engine/analyzer/common/analyzer.ts index 924607dd..19a70080 100644 --- a/src/engine/analyzer/common/analyzer.ts +++ b/src/engine/analyzer/common/analyzer.ts @@ -2123,7 +2123,8 @@ class Analyzer extends MemSpace { // attach taint information if any // var taint; - for (const arg of argvalues) { + for (const key in argvalues) { + const arg = argvalues[key] if (arg) { if (arg.hasTagRec) { res.hasTagRec = true @@ -2137,7 +2138,8 @@ class Analyzer extends MemSpace { } // e.g. XXInterface token = XXInterface(id) where id is ctor_init - for (const arg of argvalues) { + for (const key in argvalues) { + const arg = argvalues[key] if (arg && arg.ctor_init && node.expression && node.expression.value) { let top_scope = scope while (top_scope.parent) { @@ -2159,7 +2161,7 @@ class Analyzer extends MemSpace { res = SymbolValue(res) // esp. for member getter function // save pass-in arguments for later use - if (argvalues.length > 0) { + if (Object.keys(argvalues).length > 0) { res.setMisc('pass-in', argvalues) } return res @@ -2229,7 +2231,12 @@ class Analyzer extends MemSpace { scope: any, state: any ) { - if (!argvalues || argvalues.length < 2 || !targetIndex || targetIndex >= argvalues.length) { + if ( + !argvalues || + Object.keys(argvalues).length < 2 || + !targetIndex || + targetIndex >= Object.keys(argvalues).length + ) { return } const res = argvalues[targetIndex] @@ -2464,14 +2471,18 @@ class Analyzer extends MemSpace { if (param) { paramLength = Array.isArray(param) ? param.length : param.parameters.length } - if (paramLength === argvalues.length) { + if (paramLength === Object.keys(argvalues).length) { let typeMatch = true const literalTypeList = ['String', 'string', 'int', 'Integer', 'Double', 'double', 'float', 'Float'] for (let i = 0; i < paramLength; i++) { + let argv = argvalues[i] + if (!argv && param[i].id?.name) { + argv = argvalues[param[i].id.name] + } if ( - param[i].varType?.id?.name === argvalues[i].rtype?.definiteType?.name || - argvalues[i].rtype?.definiteType?.name?.endsWith(`.${param[i].varType?.id?.name}`) || - (argvalues[i].vtype === 'primitive' && literalTypeList.includes(param[i].varType?.id?.name)) + param[i].varType?.id?.name === argv?.rtype?.definiteType?.name || + argv?.rtype?.definiteType?.name?.endsWith(`.${param[i].varType?.id?.name}`) || + (argv?.vtype === 'primitive' && literalTypeList.includes(param[i].varType?.id?.name)) ) { continue } @@ -2493,7 +2504,7 @@ class Analyzer extends MemSpace { if (param) { paramLength = Array.isArray(param) ? param.length : param.parameters.length } - if (paramLength === argvalues.length) { + if (paramLength === Object.keys(argvalues).length) { fclos = _.clone(fclos) fclos.ast = fclos.fdef = fdecl = f // adjust to the right function definition break @@ -2557,8 +2568,14 @@ class Analyzer extends MemSpace { // this.lastReturnValue = fclos.execute.call(this, fclos, argvalues, new_state, node, scope); this.lastReturnValue = null - for (let i = 0; i < argvalues.length; i++) { - argvalues[i] = SourceLine.addSrcLineInfo(argvalues[i], node, node.loc && node.loc.sourcefile, 'CALL: ', fname) + for (const key in argvalues) { + argvalues[key] = SourceLine.addSrcLineInfo( + argvalues[key], + node, + node.loc && node.loc.sourcefile, + 'CALL: ', + fname + ) } return_value = fclos.execute.call(this, fclos, argvalues, new_state, node, scope) } else { @@ -2585,10 +2602,10 @@ class Analyzer extends MemSpace { this.processInstruction(fscope, param, new_state) }) - const size = Math.min(argvalues.length, params.length) + const size = params.length let hasVariadicElement = false if ( - argvalues.length > size && + Object.keys(argvalues).length > size && ((Config.language !== 'js' && Config.language !== 'javascript') || params[params.length - 1]?._meta.isRestElement) ) { @@ -2600,11 +2617,10 @@ class Analyzer extends MemSpace { const paramName = param.id?.name if (i === size - 1 && hasVariadicElement) { // variadic parameter processing - const rest_argvalues = argvalues.slice(i) const rest_val: any = {} - rest_argvalues.forEach((element: any, index: any) => { - rest_val[index.toString()] = element - }) + for (let j = 0; argvalues[i + j]; j++) { + rest_val[j.toString()] = argvalues[i + j] + } val = ObjectValue({ id: paramName, @@ -2612,15 +2628,16 @@ class Analyzer extends MemSpace { }) } else { if (!paramName) continue // unused parameters - let index = i - if (node.names && node.names.length > 0) { - // handle named argument values like "f({value: 2, key: 3})" - const k = node.names.indexOf(param.name) - if (k !== -1) index = k + const argKeys = Object.keys(argvalues) + if (argKeys.includes(paramName)) { + index = paramName } - // if (DEBUG) logger.info('write arg:' + formatNode(param) + ' = ' + formatNode(argvalues[i])); + val = argvalues[index] + if (!val) { + continue + } } // add source line information @@ -2807,7 +2824,7 @@ class Analyzer extends MemSpace { this.executeFunctionInArguments(scope, fclos, node, argvalues, state) } // save pass-in arguments for later use - if (argvalues.length > 0) { + if (Object.keys(argvalues).length > 0) { if (!obj.arguments || (Array.isArray(obj.arguments) && obj.arguments?.length === 0)) { obj.arguments = argvalues } else { @@ -2861,24 +2878,25 @@ class Analyzer extends MemSpace { } if (paras) { if (paras.type === 'ParameterList') paras = paras.parameters - const len = Math.min(paras.length, argvalues.length) - for (let i = 0; i < len; i++) { - const param = paras[i] - let index = i - const names = node.names || node.arguments - if (names > 0) { - // handle named argument values like "f({value: 2, key: 3})" - const k = names.indexOf(param.name) - if (k !== -1) index = k - } - let val = argvalues[index] - // add source line information - if (param.loc) { - val = SourceLine.addSrcLineInfo(val, node, param.loc.sourcefile, 'CTOR ARG PASS: ', param.name) + const indices = Object.keys(paras) + for (const key in argvalues) { + let param + if (indices.includes(key)) { + param = paras[key] + } else { + param = paras.find((para: any) => para.id && para.id.name === key) } - if (fdef.type === 'StructDefinition') { - this.saveVarInCurrentScope(obj, param, val, state) + if (param) { + let val = argvalues[key] + // add source line information + if (param.loc) { + val = SourceLine.addSrcLineInfo(val, node, param.loc.sourcefile, 'CTOR ARG PASS: ', param.name) + } + + if (fdef.type === 'StructDefinition') { + this.saveVarInCurrentScope(obj, param, val, state) + } } } } @@ -2918,7 +2936,7 @@ class Analyzer extends MemSpace { const needInvoke = Config.invokeCallbackOnUnknownFunction if (needInvoke !== 1 && needInvoke !== 2) return UndefinedValue() - for (let i = 0; i < argvalues.length; i++) { + for (const i in argvalues) { const arg = argvalues[i] if (arg && arg.vtype === 'fclos') { const fclos = _.clone(arg) diff --git a/src/engine/analyzer/common/entrypoint.ts b/src/engine/analyzer/common/entrypoint.ts index 03a7efa1..6bc93e11 100644 --- a/src/engine/analyzer/common/entrypoint.ts +++ b/src/engine/analyzer/common/entrypoint.ts @@ -6,7 +6,7 @@ const constant = require('../../../util/constant') export interface EntryPoint { type?: string scopeVal?: any - argValues?: any[] + argValues?: Record entryPointSymVal?: { ast?: { loc?: any @@ -28,7 +28,7 @@ class EntryPointClass implements EntryPoint { scopeVal: any - argValues: any[] + argValues: Record entryPointSymVal: any diff --git a/src/engine/analyzer/common/native-resolver.ts b/src/engine/analyzer/common/native-resolver.ts index 0003557f..72084531 100644 --- a/src/engine/analyzer/common/native-resolver.ts +++ b/src/engine/analyzer/common/native-resolver.ts @@ -312,7 +312,7 @@ function simplifyArrayExpression(obj: any, index: any): any { * @param argvalues * @returns {*} */ -function nativeCall(obj: any, f: any, argvalues: any[]): any { +function nativeCall(obj: any, f: any, argvalues: Record): any { const fname = f.name // array operations if (Array.isArray(obj)) { @@ -340,7 +340,7 @@ function nativeCall(obj: any, f: any, argvalues: any[]): any { // return obj.concat(argvalues); // } case 'push': { - return obj.push(argvalues) + return obj.push(Object.values(argvalues)) } // case 'pop': // { @@ -361,9 +361,9 @@ function nativeCall(obj: any, f: any, argvalues: any[]): any { const val = obj.value const args: any[] = [] - for (let i = 0; i < argvalues.length; i++) { - if (argvalues[i].type === 'Literal') - args.push(argvalues[i].value) // not concrete value + for (const key in argvalues) { + if (argvalues[key].type === 'Literal') + args.push(argvalues[key].value) // not concrete value else return } @@ -382,7 +382,13 @@ function nativeCall(obj: any, f: any, argvalues: any[]): any { * @param state * @returns {*} */ -function processNativeFunction(this: any, node: any, fclos: any, argvalues: any[], state: any): any { +function processNativeFunction( + this: any, + node: any, + fclos: any, + argvalues: Record, + state: any +): any { if (!fclos.id) return const { parent } = fclos @@ -409,7 +415,7 @@ function processNativeFunction(this: any, node: any, fclos: any, argvalues: any[ case 'Array': { switch (fclos.id) { case 'isArray': { - const val = argvalues.length == 0 ? false : Array.isArray(argvalues[0]) + const val = Object.keys(argvalues).length == 0 ? false : Array.isArray(argvalues[0]) return PrimitiveValue({ type: 'Literal', value: val, raw: val }) } } @@ -423,7 +429,7 @@ function processNativeFunction(this: any, node: any, fclos: any, argvalues: any[ // if (argvalues.length > 1 && argvalues[1].type === 'Literal') // logger.info(util.inspect(argvalues[0], {depth: argvalues[1].value})); // else { - for (const arg of argvalues) logger.info(util.inspect(arg, { depth: 6 })) + for (const arg of Object.values(argvalues)) logger.info(util.inspect(arg, { depth: 6 })) // } return true case 'debug': @@ -440,7 +446,7 @@ function processNativeFunction(this: any, node: any, fclos: any, argvalues: any[ } if (fid.startsWith('print_')) { const fd = fid.substring(6) - for (const arg of argvalues) logger.info(util.inspect(arg[fd], { depth: 6 })) + for (const arg of Object.values(argvalues)) logger.info(util.inspect(arg[fd], { depth: 6 })) return true } } diff --git a/src/engine/analyzer/golang/common/go-analyzer.ts b/src/engine/analyzer/golang/common/go-analyzer.ts index e6a72039..bd0ed43a 100644 --- a/src/engine/analyzer/golang/common/go-analyzer.ts +++ b/src/engine/analyzer/golang/common/go-analyzer.ts @@ -1143,8 +1143,7 @@ class GoAnalyzer extends Analyzer { const needInvoke = Config.invokeCallbackOnUnknownFunction if (needInvoke !== 1 && needInvoke !== 2) return - for (let i = 0; i < argvalues.length; i++) { - const arg = argvalues[i] + for (const arg of argvalues) { if (arg && arg.vtype === 'object') { const obj = _.clone(arg) // 浅拷贝即可 const newState = _.clone(state) diff --git a/src/engine/analyzer/golang/gin/entrypoint-collector/gin-default-entrypoint.ts b/src/engine/analyzer/golang/gin/entrypoint-collector/gin-default-entrypoint.ts index c7ca91e6..96ebe001 100644 --- a/src/engine/analyzer/golang/gin/entrypoint-collector/gin-default-entrypoint.ts +++ b/src/engine/analyzer/golang/gin/entrypoint-collector/gin-default-entrypoint.ts @@ -119,7 +119,12 @@ function getGinEntryPointAndSource(packageManager: any) { * @param scope * @returns {null} */ -function collectRouteRegistry(callExpNode: any, calleeObject: any, argValues: any[], scope: any) { +function collectRouteRegistry( + callExpNode: any, + calleeObject: any, + argValues: Record, + scope: any +) { const routeFCloses: any[] = [] const propertyName = callExpNode.callee.property?.name const objectQid = calleeObject._qid @@ -128,7 +133,7 @@ function collectRouteRegistry(callExpNode: any, calleeObject: any, argValues: an RouteRegistryObject.some((ginPrefix) => objectQid?.startsWith(ginPrefix)) && RouteRegistryProperty.includes(propertyName) ) { - for (const arg of argValues) { + for (const arg of Object.values(argValues)) { if (arg?.vtype === 'fclos' && arg.ast?.loc) { // 避免对同一条路由注册语句重复添加 const hash = JSON.stringify(arg.ast.loc) diff --git a/src/engine/analyzer/java/common/builtins/atomicreference-builtins.ts b/src/engine/analyzer/java/common/builtins/atomicreference-builtins.ts index 62f68fa3..69304d71 100644 --- a/src/engine/analyzer/java/common/builtins/atomicreference-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/atomicreference-builtins.ts @@ -16,12 +16,12 @@ class AtomicReference { * @param scope * @constructor */ - static AtomicReference(_this: any, argvalues: any[], state: any, node: any, scope: any): any { + static AtomicReference(_this: any, argvalues: Record, state: any, node: any, scope: any): any { if (!_this) { return _this } - if (argvalues.length > 0) { + if (Object.keys(argvalues).length > 0) { memSpaceUtilAtomic.saveVarInScope(_this, '_value', argvalues[0], state) } @@ -36,7 +36,7 @@ class AtomicReference { * @param node * @param scope */ - static set(fclos: any, argvalues: any[], state: any, node: any, scope: any): void { + static set(fclos: any, argvalues: Record, state: any, node: any, scope: any): void { const _this = fclos.getThis() if (!_this) { return new UndefinedValueAtomic() diff --git a/src/engine/analyzer/java/common/builtins/collection-builtins.ts b/src/engine/analyzer/java/common/builtins/collection-builtins.ts index f0b2f4f9..0e4aea7d 100644 --- a/src/engine/analyzer/java/common/builtins/collection-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/collection-builtins.ts @@ -11,7 +11,7 @@ class Collection { * @param scope * @constructor */ - static Collection(_this: any, argvalues: any[], state: any, node: any, scope: any) { + static Collection(_this: any, argvalues: Record, state: any, node: any, scope: any) { return _this } } diff --git a/src/engine/analyzer/java/common/builtins/completablefuture-builtins.ts b/src/engine/analyzer/java/common/builtins/completablefuture-builtins.ts index b8a62f38..9f7cd697 100644 --- a/src/engine/analyzer/java/common/builtins/completablefuture-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/completablefuture-builtins.ts @@ -19,12 +19,12 @@ class CompletableFuture { * @returns {*} * @constructor */ - static CompletableFuture(_this: any, argvalues: any[], state: any, node: any, scope: any) { + static CompletableFuture(_this: any, argvalues: Record, state: any, node: any, scope: any) { if (_this) { return _this } - if (argvalues.length > 0) { + if (Object.keys(argvalues).length > 0) { memSpaceUtil.saveVarInScope(_this, '_result', argvalues[0], state) _this.setMisc('thenFuncsWithContext', []) } @@ -40,7 +40,7 @@ class CompletableFuture { * @param node * @param scope */ - static join(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static join(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this || !(this as any).executeCall) { return new UndefinedValue() @@ -69,11 +69,11 @@ class CompletableFuture { * @param node * @param scope */ - static runAsync(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static runAsync(fclos: any, argvalues: Record, state: any, node: any, scope: any) { let instance = new UndefinedValue() if ( !(this as any).processNewExpression || - argvalues.length < 1 || + Object.keys(argvalues).length < 1 || argvalues[0].vtype !== 'fclos' || !(this as any).processAndCallFuncDef ) { @@ -116,11 +116,11 @@ class CompletableFuture { * @param node * @param scope */ - static supplyAsync(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static supplyAsync(fclos: any, argvalues: Record, state: any, node: any, scope: any) { let instance = new UndefinedValue() if ( !(this as any).processNewExpression || - argvalues.length < 1 || + Object.keys(argvalues).length < 1 || argvalues[0].vtype !== 'fclos' || !(this as any).processAndCallFuncDef ) { @@ -164,9 +164,14 @@ class CompletableFuture { * @param node * @param scope */ - static thenRun(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static thenRun(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || argvalues.length < 1 || argvalues[0].vtype !== 'fclos' || !(this as any).processAndCallFuncDef) { + if ( + !_this || + Object.keys(argvalues).length < 1 || + argvalues[0].vtype !== 'fclos' || + !(this as any).processAndCallFuncDef + ) { return new UndefinedValue() } @@ -198,7 +203,7 @@ class CompletableFuture { * @param node * @param scope */ - static thenRunAsync(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static thenRunAsync(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return CompletableFuture.thenRun(fclos, argvalues, state, node, scope) } @@ -210,9 +215,9 @@ class CompletableFuture { * @param node * @param scope */ - static thenApply(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static thenApply(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || argvalues.length < 1 || argvalues[0].vtype !== 'fclos' || !(this as any).executeCall) { + if (!_this || Object.keys(argvalues).length < 1 || argvalues[0].vtype !== 'fclos' || !(this as any).executeCall) { return new UndefinedValue() } @@ -247,7 +252,7 @@ class CompletableFuture { * @param scope * @returns {UndefinedValue|*} */ - static thenApplyAsync(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static thenApplyAsync(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return CompletableFuture.thenApply(fclos, argvalues, state, node, scope) } @@ -259,9 +264,9 @@ class CompletableFuture { * @param node * @param scope */ - static thenAccept(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static thenAccept(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || argvalues.length < 1 || argvalues[0].vtype !== 'fclos' || !(this as any).executeCall) { + if (!_this || Object.keys(argvalues).length < 1 || argvalues[0].vtype !== 'fclos' || !(this as any).executeCall) { return new UndefinedValue() } @@ -294,7 +299,7 @@ class CompletableFuture { * @param node * @param scope */ - static thenAcceptAsync(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static thenAcceptAsync(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return CompletableFuture.thenAccept(fclos, argvalues, state, node, scope) } } diff --git a/src/engine/analyzer/java/common/builtins/executor-builtins.ts b/src/engine/analyzer/java/common/builtins/executor-builtins.ts index 44302141..d3dfe9fa 100644 --- a/src/engine/analyzer/java/common/builtins/executor-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/executor-builtins.ts @@ -12,8 +12,8 @@ class Executor { * @param node * @param scope */ - static execute(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - if (argvalues.length < 1) { + static execute(fclos: any, argvalues: Record, state: any, node: any, scope: any) { + if (Object.keys(argvalues).length < 1) { return } if (argvalues[0].field?.run && _.isFunction((this as any).executeCall)) { diff --git a/src/engine/analyzer/java/common/builtins/hashmap-builtins.ts b/src/engine/analyzer/java/common/builtins/hashmap-builtins.ts index 72d73cac..204bbd12 100644 --- a/src/engine/analyzer/java/common/builtins/hashmap-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/hashmap-builtins.ts @@ -13,10 +13,10 @@ class HashMap extends (Map as any) { * @param scope * @constructor */ - static HashMap(_this: any, argvalues: any[], state: any, node: any, scope: any) { + static HashMap(_this: any, argvalues: Record, state: any, node: any, scope: any) { super.Map(_this, argvalues, state, node, scope) - if (argvalues.length === 1 && argvalues[0].vtype !== 'primitive') { + if (Object.keys(argvalues).length === 1 && argvalues[0].vtype !== 'primitive') { super.putAll(_this, argvalues, state, node, scope) } diff --git a/src/engine/analyzer/java/common/builtins/hashset-builtins.ts b/src/engine/analyzer/java/common/builtins/hashset-builtins.ts index 84220da7..b3aa3052 100644 --- a/src/engine/analyzer/java/common/builtins/hashset-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/hashset-builtins.ts @@ -13,10 +13,10 @@ class HashSet extends SetBuiltins { * @param scope * @constructor */ - static HashSet(_this: any, argvalues: any[], state: any, node: any, scope: any): any { + static HashSet(_this: any, argvalues: Record, state: any, node: any, scope: any): any { super.Set(_this, argvalues, state, node, scope) - if (argvalues.length === 1 && argvalues[0].vtype !== 'primitive') { + if (Object.keys(argvalues).length === 1 && argvalues[0].vtype !== 'primitive') { addElementToBufferHashSet(_this, argvalues[0]) } @@ -31,7 +31,7 @@ class HashSet extends SetBuiltins { * @param node * @param scope */ - static clone(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static clone(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { return fclos.getThis() } } diff --git a/src/engine/analyzer/java/common/builtins/list-builtins.ts b/src/engine/analyzer/java/common/builtins/list-builtins.ts index 2ba18bf0..9ef496c4 100644 --- a/src/engine/analyzer/java/common/builtins/list-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/list-builtins.ts @@ -19,7 +19,7 @@ class List extends (Collection as any) { * @param scope * @private */ - static List(_this: any, argvalues: any[], state: any, node: any, scope: any) { + static List(_this: any, argvalues: Record, state: any, node: any, scope: any) { super.Collection(_this, argvalues, state, node, scope) _this.setMisc('precise', true) @@ -34,9 +34,9 @@ class List extends (Collection as any) { * @param node * @param scope */ - static add(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static add(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return new UndefinedValue() } @@ -44,10 +44,10 @@ class List extends (Collection as any) { addElementToBuffer(_this, argvalues[0]) } else { _this.length = _this.length ?? 0 - if (argvalues.length === 1) { + if (Object.keys(argvalues).length === 1) { _this.value[_this.length] = argvalues[0] _this.length++ - } else if (argvalues.length === 2) { + } else if (Object.keys(argvalues).length === 2) { const indexVal = argvalues[0] if (indexVal?.vtype === 'primitive' && indexVal?.type === 'Literal' && indexVal?.literalType === 'number') { const index = parseInt(indexVal.value, 10) @@ -66,7 +66,7 @@ class List extends (Collection as any) { } } - if (argvalues.length === 1) { + if (Object.keys(argvalues).length === 1) { return new UndefinedValue() } } @@ -79,9 +79,9 @@ class List extends (Collection as any) { * @param node * @param scope */ - static addAll(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static addAll(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return new UndefinedValue() } @@ -101,9 +101,9 @@ class List extends (Collection as any) { * @param node * @param scope */ - static addFirst(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static addFirst(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return } @@ -134,10 +134,10 @@ class List extends (Collection as any) { * @param node * @param scope */ - static addLast(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static addLast(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return } @@ -158,7 +158,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static clear(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static clear(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return @@ -189,7 +189,7 @@ class List extends (Collection as any) { * @param scope * @returns {null} */ - static contains(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static contains(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -202,7 +202,7 @@ class List extends (Collection as any) { * @param scope * @returns {null} */ - static containsAll(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static containsAll(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -214,7 +214,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static equals(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static equals(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -227,7 +227,7 @@ class List extends (Collection as any) { * @param scope * @returns {{type, object, property}|*} */ - static get(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static get(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return new UndefinedValue() @@ -247,7 +247,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static getFirst(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static getFirst(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return new UndefinedValue() @@ -267,7 +267,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static getLast(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static getLast(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return new UndefinedValue() @@ -290,7 +290,7 @@ class List extends (Collection as any) { * @param scope * @returns {null} */ - static hashCode(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static hashCode(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -303,7 +303,7 @@ class List extends (Collection as any) { * @param scope * @returns {null} */ - static indexOf(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static indexOf(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -316,7 +316,7 @@ class List extends (Collection as any) { * @param scope * @returns {null} */ - static isEmpty(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static isEmpty(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -328,7 +328,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static iterator(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static iterator(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return new UndefinedValue() @@ -358,7 +358,7 @@ class List extends (Collection as any) { * @param scope * @returns {null} */ - static lastIndexOf(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static lastIndexOf(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -370,7 +370,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static listIterator(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static listIterator(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this || !argvalues) { return new UndefinedValue() @@ -391,9 +391,9 @@ class List extends (Collection as any) { } } - if (argvalues.length === 0) { + if (Object.keys(argvalues).length === 0) { moveExistElementsToBuffer(newThis) - } else if (argvalues.length === 1) { + } else if (Object.keys(argvalues).length === 1) { let index: number = 0 const indexVal = argvalues[0] if (indexVal?.vtype === 'primitive' && indexVal?.type === 'Literal' && indexVal?.literalType === 'number') { @@ -413,9 +413,9 @@ class List extends (Collection as any) { * @param node * @param scope */ - static remove(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static remove(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return new UndefinedValue() } @@ -488,9 +488,9 @@ class List extends (Collection as any) { * @param node * @param scope */ - static removeAll(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static removeAll(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (_this || !argvalues || argvalues.length === 0) { + if (_this || !argvalues || Object.keys(argvalues).length === 0) { return new UndefinedValue() } @@ -510,7 +510,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static removeFirst(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static removeFirst(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return new UndefinedValue() @@ -550,7 +550,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static removeLast(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static removeLast(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return new UndefinedValue() @@ -578,7 +578,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static replaceAll(fclos: any, argvalues: any[], state: any, node: any, scope: any) {} + static replaceAll(fclos: any, argvalues: Record, state: any, node: any, scope: any) {} /** * List.retainAll @@ -588,9 +588,9 @@ class List extends (Collection as any) { * @param node * @param scope */ - static retainAll(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static retainAll(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!argvalues || argvalues.length === 0) { + if (!argvalues || Object.keys(argvalues).length === 0) { return new UndefinedValue() } @@ -608,7 +608,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static reversed(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static reversed(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return new UndefinedValue() @@ -639,10 +639,10 @@ class List extends (Collection as any) { * @param node * @param scope */ - static set(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static set(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length !== 2) { + if (!_this || !argvalues || Object.keys(argvalues).length !== 2) { return new UndefinedValue() } @@ -678,7 +678,7 @@ class List extends (Collection as any) { * @param scope * @returns {null} */ - static size(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static size(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -690,7 +690,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static sort(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static sort(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return @@ -709,7 +709,7 @@ class List extends (Collection as any) { * @param node * @param scope */ - static spliterator(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static spliterator(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return List.iterator(fclos, argvalues, state, node, scope) } @@ -721,9 +721,9 @@ class List extends (Collection as any) { * @param node * @param scope */ - static subList(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static subList(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length !== 2) { + if (!_this || !argvalues || Object.keys(argvalues).length !== 2) { return new UndefinedValue() } @@ -804,7 +804,7 @@ class List extends (Collection as any) { * @param scope * @returns {*} */ - static toArray(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static toArray(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return fclos.getThis() } @@ -817,7 +817,13 @@ class List extends (Collection as any) { * @param scope * @private */ - static _functionNotFoundCallback_(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static _functionNotFoundCallback_( + fclos: any, + argvalues: Record, + state: any, + node: any, + scope: any + ) { const _this = fclos.getThis() if (!_this) { return diff --git a/src/engine/analyzer/java/common/builtins/lombok.ts b/src/engine/analyzer/java/common/builtins/lombok.ts index 0bd326a2..ecd3eb9e 100644 --- a/src/engine/analyzer/java/common/builtins/lombok.ts +++ b/src/engine/analyzer/java/common/builtins/lombok.ts @@ -8,8 +8,8 @@ module.exports = { */ processGetter(fname: any, fieldName: any) { return function getter(fclos: any, argvalues: any, state: any, node: any, scope: any) { - if (argvalues.length !== 0) { - logger.warn('getter: params length [%d] is not equal to 0', argvalues.length) + if (Object.keys(argvalues).length !== 0) { + logger.warn('getter: params length [%d] is not equal to 0', Object.keys(argvalues).length) } return fclos.getThis().getFieldValue(fieldName, true) } @@ -23,8 +23,8 @@ module.exports = { // } // 没有入参,会把符号值变为undefined return function setter(fclos: any, argvalues: any, state: any, node: any, scope: any) { - if (argvalues.length !== 1) { - logger.warn('setter: params length [%d] is not equal to 1', argvalues.length) + if (Object.keys(argvalues).length !== 1) { + logger.warn('setter: params length [%d] is not equal to 1', Object.keys(argvalues).length) } fclos.getThis().setFieldValue(fieldName, argvalues[0]) return fclos.getThis() diff --git a/src/engine/analyzer/java/common/builtins/map-builtins.ts b/src/engine/analyzer/java/common/builtins/map-builtins.ts index f0ee4204..f4380119 100644 --- a/src/engine/analyzer/java/common/builtins/map-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/map-builtins.ts @@ -19,7 +19,7 @@ class Map extends (Collection as any) { * @param scope * @constructor */ - static Map(_this: any, argvalues: any[], state: any, node: any, scope: any) { + static Map(_this: any, argvalues: Record, state: any, node: any, scope: any) { super.Collection(_this, argvalues, state, node, scope) _this.setMisc('precise', true) @@ -37,7 +37,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static clear(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static clear(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.parent if (!_this) { return @@ -65,7 +65,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static compute(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static compute(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return Map.get(fclos, argvalues, state, node, scope) } @@ -77,7 +77,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static computeIfAbsent(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static computeIfAbsent(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -89,7 +89,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static computeIfPresent(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static computeIfPresent(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return Map.get(fclos, argvalues, state, node, scope) } @@ -101,7 +101,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static containsKey(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static containsKey(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -113,7 +113,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static containsValue(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static containsValue(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -125,7 +125,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static entrySet(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static entrySet(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return new UndefinedValue() @@ -145,7 +145,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static equals(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static equals(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -157,7 +157,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static forEach(fclos: any, argvalues: any[], state: any, node: any, scope: any) {} + static forEach(fclos: any, argvalues: Record, state: any, node: any, scope: any) {} /** * Map.get @@ -167,9 +167,9 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static get(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static get(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return new UndefinedValue() } @@ -196,9 +196,9 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static getOrDefault(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static getOrDefault(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const element = Map.get(fclos, argvalues, state, node, scope) - if ((!element || element.vtype === 'undefine') && argvalues.length === 2) { + if ((!element || element.vtype === 'undefine') && Object.keys(argvalues).length === 2) { return argvalues[1] } return element @@ -213,7 +213,7 @@ class Map extends (Collection as any) { * @param scope * @returns {null} */ - static hashCode(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static hashCode(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -226,7 +226,7 @@ class Map extends (Collection as any) { * @param scope * @returns {null} */ - static isEmpty(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static isEmpty(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -238,7 +238,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static keySet(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static keySet(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return new UndefinedValue() @@ -273,9 +273,9 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static merge(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static merge(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length < 3) { + if (!_this || !argvalues || Object.keys(argvalues).length < 3) { return new UndefinedValue() } @@ -292,9 +292,9 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static put(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static put(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length < 2) { + if (!_this || !argvalues || Object.keys(argvalues).length < 2) { return new UndefinedValue() } @@ -328,9 +328,9 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static putAll(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static putAll(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return } @@ -367,9 +367,9 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static putIfAbsent(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static putIfAbsent(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length < 2) { + if (!_this || !argvalues || Object.keys(argvalues).length < 2) { return new UndefinedValue() } @@ -389,9 +389,9 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static remove(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static remove(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length < 1) { + if (!_this || !argvalues || Object.keys(argvalues).length < 1) { return new UndefinedValue() } @@ -404,12 +404,12 @@ class Map extends (Collection as any) { const entryValue = _this.getFieldValue(keyRef) if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { const value = entryValue.field[1] - if (argvalues.length === 1) { + if (Object.keys(argvalues).length === 1) { keyRefSet.delete(keyRef) delete _this.field[keyRef] return value } - if (argvalues.length === 2 && value?._qid === argvalues[1]._qid) { + if (Object.keys(argvalues).length === 2 && value?._qid === argvalues[1]._qid) { keyRefSet.delete(keyRef) delete _this.field[keyRef] return new UndefinedValue() @@ -425,9 +425,9 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static replace(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static replace(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length < 2) { + if (!_this || !argvalues || Object.keys(argvalues).length < 2) { return } @@ -440,11 +440,11 @@ class Map extends (Collection as any) { const entryValue = _this.getFieldValue(keyRef) if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { const value = entryValue.field[1] - if (argvalues.length === 2) { + if (Object.keys(argvalues).length === 2) { entryValue.field[1] = argvalues[1] return value } - if (argvalues.length === 3 && value?._qid === argvalues[1]._qid) { + if (Object.keys(argvalues).length === 3 && value?._qid === argvalues[1]._qid) { entryValue.field[1] = argvalues[2] return new UndefinedValue() } @@ -459,7 +459,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static replaceAll(fclos: any, argvalues: any[], state: any, node: any, scope: any) {} + static replaceAll(fclos: any, argvalues: Record, state: any, node: any, scope: any) {} /** * Map.size @@ -469,7 +469,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static size(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static size(fclos: any, argvalues: Record, state: any, node: any, scope: any) { return new UndefinedValue() } @@ -481,7 +481,7 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static values(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + static values(fclos: any, argvalues: Record, state: any, node: any, scope: any) { const _this = fclos.getThis() if (!_this) { return new UndefinedValue() diff --git a/src/engine/analyzer/java/common/builtins/queue-builtins.ts b/src/engine/analyzer/java/common/builtins/queue-builtins.ts index 8d6579a4..a3d3faf6 100644 --- a/src/engine/analyzer/java/common/builtins/queue-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/queue-builtins.ts @@ -21,7 +21,7 @@ class Queue extends Collection { * @param scope * @private */ - static Queue(_this: any, argvalues: any[], state: any, node: any, scope: any): any { + static Queue(_this: any, argvalues: Record, state: any, node: any, scope: any): any { super.Collection(_this, argvalues, state, node, scope) _this.setMisc('precise', true) @@ -36,16 +36,16 @@ class Queue extends Collection { * @param node * @param scope */ - static add(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static add(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return new UndefinedValueQueue() } if (!_this.getMisc('precise')) { addElementToBufferQueue(_this, argvalues[0]) } else { _this.length = _this.length ?? 0 - if (argvalues.length === 1) { + if (Object.keys(argvalues).length === 1) { _this.value[_this.length] = argvalues[0] _this.length++ } else { @@ -67,7 +67,7 @@ class Queue extends Collection { * @param node * @param scope */ - static element(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static element(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const _this = fclos.getThis() if (!_this) { return new UndefinedValueQueue() @@ -87,7 +87,7 @@ class Queue extends Collection { * @param node * @param scope */ - static offer(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static offer(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { return Queue.add(fclos, argvalues, state, node, scope) } @@ -100,7 +100,7 @@ class Queue extends Collection { * @param scope * @returns {*|{type, object, property}} */ - static peek(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static peek(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { return Queue.element(fclos, argvalues, state, node, scope) } @@ -112,7 +112,7 @@ class Queue extends Collection { * @param node * @param scope */ - static poll(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static poll(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const _this = fclos.getThis() if (!_this) { return new UndefinedValueQueue() @@ -152,7 +152,7 @@ class Queue extends Collection { * @param node * @param scope */ - static remove(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static remove(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { return Queue.poll(fclos, argvalues, state, node, scope) } @@ -165,7 +165,13 @@ class Queue extends Collection { * @param scope * @private */ - static _functionNotFoundCallback_(fclos: any, argvalues: any[], state: any, node: any, scope: any): void { + static _functionNotFoundCallback_( + fclos: any, + argvalues: Record, + state: any, + node: any, + scope: any + ): void { const _this = fclos.getThis() if (!_this) { return diff --git a/src/engine/analyzer/java/common/builtins/set-builtins.ts b/src/engine/analyzer/java/common/builtins/set-builtins.ts index a4c5281e..b153eafe 100644 --- a/src/engine/analyzer/java/common/builtins/set-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/set-builtins.ts @@ -36,7 +36,7 @@ class Set extends Collection { */ static add(fclos: any, argvalues: any, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return new UndefinedValueJava() } @@ -55,7 +55,7 @@ class Set extends Collection { */ static addAll(fclos: any, argvalues: any, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return new UndefinedValueJava() } @@ -176,7 +176,7 @@ class Set extends Collection { */ static remove(fclos: any, argvalues: any, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return new UndefinedValueJava() } @@ -195,7 +195,7 @@ class Set extends Collection { */ static removeAll(fclos: any, argvalues: any, state: any, node: any, scope: any) { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return new UndefinedValueJava() } diff --git a/src/engine/analyzer/java/common/builtins/stack-builtins.ts b/src/engine/analyzer/java/common/builtins/stack-builtins.ts index 48dad344..2cbf17d5 100644 --- a/src/engine/analyzer/java/common/builtins/stack-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/stack-builtins.ts @@ -14,7 +14,7 @@ class Stack extends List { * @param scope * @constructor */ - static Stack(_this: any, argvalues: any[], state: any, node: any, scope: any): any { + static Stack(_this: any, argvalues: Record, state: any, node: any, scope: any): any { super.List(_this, argvalues, state, node, scope) _this.setMisc('precise', true) @@ -29,7 +29,7 @@ class Stack extends List { * @param node * @param scope */ - static empty(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static empty(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { return new UndefinedValueStack() } @@ -41,7 +41,7 @@ class Stack extends List { * @param node * @param scope */ - static peek(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static peek(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { return super.getLast(fclos, argvalues, state, node, scope) } @@ -53,7 +53,7 @@ class Stack extends List { * @param node * @param scope */ - static pop(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static pop(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const lastElement = super.getLast(fclos, argvalues, state, node, scope) super.removeLast(fclos, argvalues, state, node, scope) return lastElement @@ -67,10 +67,10 @@ class Stack extends List { * @param node * @param scope */ - static push(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static push(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { super.add(fclos, argvalues, state, node, scope) - if (argvalues.length > 0) { + if (Object.keys(argvalues).length > 0) { return argvalues[0] } return new UndefinedValueStack() @@ -84,7 +84,7 @@ class Stack extends List { * @param node * @param scope */ - static search(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static search(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { return new UndefinedValueStack() } } diff --git a/src/engine/analyzer/java/common/builtins/stringbuffer-builtins.ts b/src/engine/analyzer/java/common/builtins/stringbuffer-builtins.ts index b6768f2c..6bc58058 100644 --- a/src/engine/analyzer/java/common/builtins/stringbuffer-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/stringbuffer-builtins.ts @@ -13,7 +13,7 @@ class StringBuffer { * @param scope * @constructor */ - static StringBuffer(_this: any, argvalues: any[], state: any, node: any, scope: any): any { + static StringBuffer(_this: any, argvalues: Record, state: any, node: any, scope: any): any { return _this } @@ -25,9 +25,9 @@ class StringBuffer { * @param node * @param scope */ - static append(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static append(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return } addElementToBufferStringBuffer(_this, argvalues[0]) diff --git a/src/engine/analyzer/java/common/builtins/stringbuilder-builtins.ts b/src/engine/analyzer/java/common/builtins/stringbuilder-builtins.ts index b3240aa1..5a58be15 100644 --- a/src/engine/analyzer/java/common/builtins/stringbuilder-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/stringbuilder-builtins.ts @@ -13,7 +13,7 @@ class StringBuilder { * @param scope * @constructor */ - static StringBuilder(_this: any, argvalues: any[], state: any, node: any, scope: any): any { + static StringBuilder(_this: any, argvalues: Record, state: any, node: any, scope: any): any { return _this } @@ -25,9 +25,9 @@ class StringBuilder { * @param node * @param scope */ - static append(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + static append(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + if (!_this || !argvalues || Object.keys(argvalues).length === 0) { return _this } addElementToBufferStringBuilder(_this, argvalues[0]) diff --git a/src/engine/analyzer/java/common/builtins/timer-builtins.ts b/src/engine/analyzer/java/common/builtins/timer-builtins.ts index 84870860..1a3715d7 100644 --- a/src/engine/analyzer/java/common/builtins/timer-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/timer-builtins.ts @@ -12,8 +12,8 @@ class Timer { * @param node * @param scope */ - static schedule(fclos: any, argvalues: any[], state: any, node: any, scope: any): void { - if (argvalues.length < 1) { + static schedule(fclos: any, argvalues: Record, state: any, node: any, scope: any): void { + if (Object.keys(argvalues).length < 1) { return } const maybeFn = (this as any).executeCall @@ -30,7 +30,13 @@ class Timer { * @param node * @param scope */ - static scheduleAtFixedRate(fclos: any, argvalues: any[], state: any, node: any, scope: any): void { + static scheduleAtFixedRate( + fclos: any, + argvalues: Record, + state: any, + node: any, + scope: any + ): void { Timer.schedule(fclos, argvalues, state, node, scope) } } diff --git a/src/engine/analyzer/java/common/java-analyzer.ts b/src/engine/analyzer/java/common/java-analyzer.ts index afdb69f6..dcc10e29 100644 --- a/src/engine/analyzer/java/common/java-analyzer.ts +++ b/src/engine/analyzer/java/common/java-analyzer.ts @@ -1069,7 +1069,7 @@ class JavaAnalyzer extends (Analyzer as any) { if (!fclos) return UndefinedValue() // prepare the function arguments - let argvalues: any[] = [] + let argvalues: Record = [] let sameArgs = true // minor optimization to save memory for (const arg of node.arguments) { let argv = this.processInstruction(scope, arg, state) @@ -1235,7 +1235,7 @@ class JavaAnalyzer extends (Analyzer as any) { this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) - const argValues: any[] = [] + const argValues: Record = [] try { for (const key in entryPoint.entryPointSymVal?.ast?.parameters) { argValues.push( diff --git a/src/engine/analyzer/java/spring/spring-analyzer.ts b/src/engine/analyzer/java/spring/spring-analyzer.ts index 310affba..9a7908bf 100644 --- a/src/engine/analyzer/java/spring/spring-analyzer.ts +++ b/src/engine/analyzer/java/spring/spring-analyzer.ts @@ -83,7 +83,7 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) - const argValues: any[] = [] + const argValues: Record = [] try { for (const key in entryPoint.entryPointSymVal?.ast?.parameters) { argValues.push( diff --git a/src/engine/analyzer/javascript/common/builtins/array-builtins.ts b/src/engine/analyzer/javascript/common/builtins/array-builtins.ts index 093ae931..d5d0a000 100644 --- a/src/engine/analyzer/javascript/common/builtins/array-builtins.ts +++ b/src/engine/analyzer/javascript/common/builtins/array-builtins.ts @@ -9,7 +9,14 @@ const { getDataFromScope } = require('../../../../../util/common-util') * @param node * @param scope */ -function processVisitArrayBuiltins(this: any, fclos: any, argvalues: any[], state: any, node: any, scope: any): any[] { +function processVisitArrayBuiltins( + this: any, + fclos: any, + argvalues: Record, + state: any, + node: any, + scope: any +): any[] { // 拿到foreach的参数 该参数是一个functionvalue const forEachHandle = argvalues && argvalues[0] // 校验forEachHandle 是一个function value 不是则结束 @@ -34,14 +41,21 @@ function processVisitArrayBuiltins(this: any, fclos: any, argvalues: any[], stat * @param node * @param scope */ -function processArrayPushBuiltins(fclos: any, argvalues: any[], state: any, node: any, scope: any): void { +function processArrayPushBuiltins( + fclos: any, + argvalues: Record, + state: any, + node: any, + scope: any +): void { const arrObj = fclos.parent // array没有初始化操作,没办法在array初始化的时候设置length的值 const offset = Object.keys(getDataFromScope(arrObj)).length ?? 0 - if (Array.isArray(argvalues) && argvalues.length > 0) { - for (let i = 0; i < argvalues.length; i++) { - const index = (offset + i).toString() - arrObj.setFieldValue(index, argvalues[i]) + if (Object.keys(argvalues).length > 0) { + let index = offset + for (const argvalue of Object.values(argvalues)) { + arrObj.setFieldValue(index.toString(), argvalue) + index++ } } } diff --git a/src/engine/analyzer/javascript/common/builtins/function.ts b/src/engine/analyzer/javascript/common/builtins/function.ts index c0fc076b..71542c93 100644 --- a/src/engine/analyzer/javascript/common/builtins/function.ts +++ b/src/engine/analyzer/javascript/common/builtins/function.ts @@ -16,12 +16,19 @@ module.exports = { * @param node * @param scope */ - processFunctionCall(invoke: any, argvalues: any[], state: any, node: any, scope: any) { - if (argvalues.length <= 0) { - Errors.UnexpectedValue(`argvalues.length should greater than 0`, { no_throw: true }) + processFunctionCall(invoke: any, argvalues: Record, state: any, node: any, scope: any) { + if (Object.keys(argvalues).length <= 0) { + Errors.UnexpectedValue(`Object.keys(argvalues).length should greater than 0`, { no_throw: true }) } - return processFunctionInvoke.call(this, invoke, argvalues[0], argvalues.slice(1), state, node, scope) + const sliced = [] + for (const key in argvalues) { + if (key !== '0') { + sliced.push(argvalues[key]) + } + } + + return processFunctionInvoke.call(this, invoke, argvalues[0], sliced, state, node, scope) }, /** @@ -32,13 +39,13 @@ module.exports = { * @param node * @param scope */ - processFunctionApply(invoke: any, argvalues: any[], state: any, node: any, scope: any) { - if (argvalues.length <= 0) { - Errors.UnexpectedValue(`argvalues.length should greater than 0`, { no_throw: true }) + processFunctionApply(invoke: any, argvalues: Record, state: any, node: any, scope: any) { + if (Object.keys(argvalues).length <= 0) { + Errors.UnexpectedValue(`Object.keys(argvalues).length should greater than 0`, { no_throw: true }) } - if (argvalues.length <= 1) { - argvalues.push(UndefinedValue()) - argvalues.push(UndefinedValue()) + if (Object.keys(argvalues).length <= 1) { + argvalues[Object.keys(argvalues).length] = UndefinedValue() + argvalues[Object.keys(argvalues).length] = UndefinedValue() } return processFunctionInvoke.call(this, invoke, argvalues[0], Object.values(argvalues[1].value), state, node, scope) }, @@ -57,7 +64,15 @@ module.exports = { * @param node * @param scope */ -function processFunctionInvoke(this: any, invoke: any, _this: any, argvalues: any[], state: any, node: any, scope: any) { +function processFunctionInvoke( + this: any, + invoke: any, + _this: any, + argvalues: Record, + state: any, + node: any, + scope: any +) { const fclos = invoke.parent const fscope = _.clone(fclos) fscope._this = _this diff --git a/src/engine/analyzer/javascript/common/builtins/map-builtins.ts b/src/engine/analyzer/javascript/common/builtins/map-builtins.ts index 42ff79db..b8b10f92 100644 --- a/src/engine/analyzer/javascript/common/builtins/map-builtins.ts +++ b/src/engine/analyzer/javascript/common/builtins/map-builtins.ts @@ -26,10 +26,10 @@ const SourceLine = require('../../../common/source-line') * @param node * @param scope */ -function processMapGet(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { +function processMapGet(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const mapObj = fclos.parent let res = UndefinedValue() - if (!argvalues || !Array.isArray(argvalues) || argvalues.length !== 1) return res + if (!argvalues || Object.keys(argvalues).length !== 1) return res const keyRef = getSymbolRef(argvalues[0]) const keyRefSet = mapObj.getFieldValue('keyRefSet') if (!keyRefSet.has(keyRef)) return res @@ -49,9 +49,9 @@ function processMapGet(fclos: any, argvalues: any[], state: any, node: any, scop * @param scope * @returns {*} */ -function processMapSet(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { +function processMapSet(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const mapObj = fclos.parent - if (argvalues && Array.isArray(argvalues) && argvalues.length === 2) { + if (argvalues && Object.keys(argvalues).length === 2) { const keyRef = getSymbolRef(argvalues[0]) const keyRefSet = mapObj.getFieldValue('keyRefSet') // key 相同时 覆盖 @@ -83,9 +83,15 @@ function processMapSet(fclos: any, argvalues: any[], state: any, node: any, scop * @param node * @param scope */ -function processMapDelete(fclos: any, argvalues: any[], state: any, node: any, scope: any): void { +function processMapDelete( + fclos: any, + argvalues: Record, + state: any, + node: any, + scope: any +): void { const mapObj = fclos.parent - if (!argvalues || !Array.isArray(argvalues) || argvalues.length !== 1) return + if (!argvalues || Object.keys(argvalues).length !== 1) return const keyRef = getSymbolRef(argvalues[0]) const keyRefSet = mapObj.getFieldValue('keyRefSet') if (!keyRefSet.has(keyRef)) return @@ -104,7 +110,7 @@ function processMapDelete(fclos: any, argvalues: any[], state: any, node: any, s * @param node * @param scope */ -function processMapClear(fclos: any, argvalues: any[], state: any, node: any, scope: any): void { +function processMapClear(fclos: any, argvalues: Record, state: any, node: any, scope: any): void { const mapObj = fclos.parent const keyRefSet = mapObj.getFieldValue('keyRefSet') for (const keyRef of keyRefSet) { @@ -124,7 +130,7 @@ function processMapClear(fclos: any, argvalues: any[], state: any, node: any, sc * @param node * @param scope */ -function processMapKeys(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { +function processMapKeys(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const mapObj = fclos.parent const resSet = UnionValue({ id: `${mapObj.id}-keySet`, @@ -150,7 +156,7 @@ function processMapKeys(fclos: any, argvalues: any[], state: any, node: any, sco * @param node * @param scope */ -function processMapValues(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { +function processMapValues(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const mapObj = fclos.parent const resSet = UnionValue({ id: `${mapObj.id}-valueSet`, @@ -185,7 +191,13 @@ function processMapValues(fclos: any, argvalues: any[], state: any, node: any, s * @param node * @param scope */ -function processNewMapBuiltins(map: any, argvalues: any[], state: any, node: any, scope: any): any { +function processNewMapBuiltins( + map: any, + argvalues: Record, + state: any, + node: any, + scope: any +): any { const builtinMap = { get: processMapGet, set: processMapSet, @@ -199,7 +211,7 @@ function processNewMapBuiltins(map: any, argvalues: any[], state: any, node: any const keyRefSet = new Set() // 有参数初始化map - if (Array.isArray(argvalues) && argvalues.length > 0) { + if (Object.keys(argvalues).length > 0) { const entries = argvalues[0]?.field && Object.entries(argvalues[0]?.field) // map的初始化 // 通过数组显示初始化 可能有 ObjectValue符号值 diff --git a/src/engine/analyzer/javascript/common/builtins/promise.ts b/src/engine/analyzer/javascript/common/builtins/promise.ts index 633e4b06..81884bd2 100644 --- a/src/engine/analyzer/javascript/common/builtins/promise.ts +++ b/src/engine/analyzer/javascript/common/builtins/promise.ts @@ -12,7 +12,14 @@ const { * @param node * @param scope */ -function processThen(this: any, fclos: any, argvalues: any[], state: any, node: any, scope: any): any { +function processThen( + this: any, + fclos: any, + argvalues: Record, + state: any, + node: any, + scope: any +): any { const handleFulfilled = argvalues && argvalues[0] const promise = fclos.parent if (handleFulfilled) { @@ -38,7 +45,14 @@ function processThen(this: any, fclos: any, argvalues: any[], state: any, node: * @param node * @param scope */ -function processCatch(this: any, fclos: any, argvalues: any[], state: any, node: any, scope: any): any { +function processCatch( + this: any, + fclos: any, + argvalues: Record, + state: any, + node: any, + scope: any +): any { const handleFulfilled = argvalues && argvalues[0] const promise = fclos.parent if (handleFulfilled) { @@ -49,14 +63,14 @@ function processCatch(this: any, fclos: any, argvalues: any[], state: any, node: reject = PromiseUndefinedValue() } // 把catch的参数值当成 fclos 参数error替换成reject接受的参数信息 - (this as any).executeCall(node, handleFulfilled, [reject], state, scope) + ;(this as any).executeCall(node, handleFulfilled, [reject], state, scope) } } return promise } module.exports = { - processPromise(promise: any, argvalues: any[], state: any, node: any, scope: any): void { + processPromise(promise: any, argvalues: Record, state: any, node: any, scope: any): void { /** * * @param val @@ -80,7 +94,13 @@ module.exports = { * @param node * @param scope */ - function processReject(fclos: any, argvalues: any[], state: any, node: any, scope: any): void { + function processReject( + fclos: any, + argvalues: Record, + state: any, + node: any, + scope: any + ): void { _process(argvalues[0], 'reject') } @@ -92,7 +112,13 @@ module.exports = { * @param node * @param scope */ - function processResolve(fclos: any, argvalues: any[], state: any, node: any, scope: any): void { + function processResolve( + fclos: any, + argvalues: Record, + state: any, + node: any, + scope: any + ): void { _process(argvalues[0], 'resolve') } diff --git a/src/engine/analyzer/javascript/common/builtins/require.ts b/src/engine/analyzer/javascript/common/builtins/require.ts index 35fc3f88..e7b7d3f9 100644 --- a/src/engine/analyzer/javascript/common/builtins/require.ts +++ b/src/engine/analyzer/javascript/common/builtins/require.ts @@ -9,9 +9,9 @@ module.exports = { * @param node * @param scope */ - processRequire(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { - if (argvalues.length !== 1) { - logger.warn('require: params length [%d] is not equal to 1', argvalues.length) + processRequire(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { + if (Object.keys(argvalues).length !== 1) { + logger.warn('require: params length [%d] is not equal to 1', Object.keys(argvalues).length) } let argNode: any if (node.type === 'CallExpression') { diff --git a/src/engine/analyzer/javascript/common/builtins/set-builtins.ts b/src/engine/analyzer/javascript/common/builtins/set-builtins.ts index 3bca8d9b..ab487be8 100644 --- a/src/engine/analyzer/javascript/common/builtins/set-builtins.ts +++ b/src/engine/analyzer/javascript/common/builtins/set-builtins.ts @@ -13,7 +13,7 @@ const { getSymbolRef } = require('../../../../../util/common-util') * @param node * @param scope */ -function processSetAdd(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { +function processSetAdd(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const setObj = fclos.parent const argval = argvalues && argvalues[0] if (!argval) return setObj @@ -33,7 +33,7 @@ function processSetAdd(fclos: any, argvalues: any[], state: any, node: any, scop * @param node * @param scope */ -function processSetDelete(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { +function processSetDelete(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const setObj = fclos.parent const argval = argvalues && argvalues[0] if (!argval) return setObj @@ -53,7 +53,7 @@ function processSetDelete(fclos: any, argvalues: any[], state: any, node: any, s * @param node * @param scope */ -function processSetClear(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { +function processSetClear(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { const setObj = fclos.parent const curSet = setObj.getFieldValue('curSet') for (const eleRef of curSet) { @@ -75,7 +75,7 @@ function processSetClear(fclos: any, argvalues: any[], state: any, node: any, sc * @param node * @param scope */ -function processSetKeys(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { +function processSetKeys(fclos: any, argvalues: Record, state: any, node: any, scope: any): any { return fclos.parent } @@ -87,7 +87,13 @@ function processSetKeys(fclos: any, argvalues: any[], state: any, node: any, sco * @param node * @param scope */ -function processNewSetBuiltins(set: any, argvalues: any[], state: any, node: any, scope: any): any { +function processNewSetBuiltins( + set: any, + argvalues: Record, + state: any, + node: any, + scope: any +): any { const builtinMap = { add: processSetAdd, clear: processSetClear, @@ -99,9 +105,10 @@ function processNewSetBuiltins(set: any, argvalues: any[], state: any, node: any initInnerFunctionBuiltin(set, builtinMap, 'Set') const curSet = new Set() - if (Array.isArray(argvalues) && argvalues.length > 0) { + if (Object.keys(argvalues).length > 0) { // 去重添加 - for (const ele of argvalues) { + for (const key in argvalues) { + const ele = argvalues[key] const uid = getSymbolRef(ele) if (!curSet.has(uid)) { curSet.add(uid) diff --git a/src/engine/analyzer/javascript/common/js-analyzer.ts b/src/engine/analyzer/javascript/common/js-analyzer.ts index 5db804d1..740d3b1e 100644 --- a/src/engine/analyzer/javascript/common/js-analyzer.ts +++ b/src/engine/analyzer/javascript/common/js-analyzer.ts @@ -53,7 +53,7 @@ class JsAnalyzer extends Analyzer { /** * 单文件预处理:解析并处理单个文件 - * + * * @param source - 源代码内容 * @param fileName - 文件名 */ @@ -65,10 +65,10 @@ class JsAnalyzer extends Analyzer { this.performanceTracker.start('preProcess.parseCode') this.uast = this.parseUast(source, fileName) this.performanceTracker.end('preProcess.parseCode') - + if (this.uast) { this.initModuleScope(this.uast, fileName) - + // 注意:直接调用 processModule 处理已解析的 AST,避免调用 processModuleSrc 导致重复解析 this.performanceTracker.start('preProcess.processModule') this.processModule(this.uast, fileName) @@ -78,7 +78,7 @@ class JsAnalyzer extends Analyzer { /** * 预处理阶段:扫描模块并解析代码 - * + * * @param dir - 项目目录 */ preProcess(dir: any) { @@ -124,7 +124,7 @@ class JsAnalyzer extends Analyzer { this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) - const argValues: any[] = [] + const argValues: Record = [] for (const key in entryPoint.entryPointSymVal?.ast?.parameters) { argValues.push( this.processInstruction( @@ -231,7 +231,7 @@ class JsAnalyzer extends Analyzer { /** * 处理模块源代码:解析并处理单个模块 - * + * * @param source - 源代码内容 * @param filename - 文件名 * @returns 处理结果 @@ -734,7 +734,7 @@ class JsAnalyzer extends Analyzer { (res as any).value[val].vtype === 'fclos' && (res as any).value[val].fdef ) { - const argvalues: any[] = [] + const argvalues: Record = [] if ((res as any).value[val].fdef?.parameters && (res as any).value[val].fdef.parameters.length > 0) { for (const para of (res as any).value[val].fdef.parameters) { const argv = this.processInstruction(scope, para, state) diff --git a/src/engine/analyzer/javascript/egg/egg-analyzer.ts b/src/engine/analyzer/javascript/egg/egg-analyzer.ts index 04e2f9ae..9882338f 100644 --- a/src/engine/analyzer/javascript/egg/egg-analyzer.ts +++ b/src/engine/analyzer/javascript/egg/egg-analyzer.ts @@ -167,16 +167,24 @@ class EggAnalyzer extends (JsAnalyzer as any) { * @param valExport * @param state */ - replaceCtxInFunctionParams(astNode: any, argValues: any[], entryPointSymVal: any, valExport: any, state: any) { + replaceCtxInFunctionParams( + astNode: any, + argValues: Record, + entryPointSymVal: any, + valExport: any, + state: any + ) { if (astNode?.type === 'FunctionDefinition') { - if (Array.isArray(astNode.parameters) && astNode.parameters?.length > 0) { + if (astNode.parameters?.length > 0) { for (const key in astNode.parameters) { if (astNode.parameters[key].id?.name === 'ctx') { // 进一步判断有没有decorator @Context。暂时不判断 - argValues.push(valExport.value.ctx) + argValues[Object.keys(argValues).length] = valExport.value.ctx } else { - argValues.push( - this.processInstruction(cloneWithDepth(entryPointSymVal, 2), astNode.parameters[key].id, state) + argValues[Object.keys(argValues).length] = this.processInstruction( + cloneWithDepth(entryPointSymVal, 2), + astNode.parameters[key].id, + state ) } } diff --git a/src/engine/analyzer/python/common/python-analyzer.ts b/src/engine/analyzer/python/common/python-analyzer.ts index 427ad6df..f7b7fd7a 100644 --- a/src/engine/analyzer/python/common/python-analyzer.ts +++ b/src/engine/analyzer/python/common/python-analyzer.ts @@ -136,15 +136,13 @@ class PythonAnalyzer extends (Analyzer as any) { this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) - const argValues: any[] = [] + const argValues: Record = {} try { for (const key in entryPoint.entryPointSymVal?.ast?.parameters) { - argValues.push( - this.processInstruction( - entryPoint.entryPointSymVal, - entryPoint.entryPointSymVal?.ast?.parameters[key]?.id, - state - ) + argValues[key] = this.processInstruction( + entryPoint.entryPointSymVal, + entryPoint.entryPointSymVal?.ast?.parameters[key]?.id, + state ) } } catch (e) { @@ -265,54 +263,23 @@ class PythonAnalyzer extends (Analyzer as any) { } if (!fclos) return UndefinedValue() - const argvalues: any[] = [] - /** - * - * @param paramAST - * @param positionalArgs - * @param keywordArgs - * @param len - */ - function collectArgsFromArray( - paramAST: any[], - positionalArgs: any[], - keywordArgs: Record, - len: number - ) { - const paramNames = paramAST.map((n: any) => n.id.name) - const collectedArgs = new Array(len).fill(undefined) - positionalArgs.forEach((arg, index) => { - if (index < collectedArgs.length) collectedArgs[index] = arg - }) - for (const [key, value] of Object.entries(keywordArgs)) { - const paramIndex = paramNames.indexOf(key) - if (paramIndex !== -1) collectedArgs[paramIndex] = value - } - return collectedArgs - } - - const positionalArgs: any[] = [] - const keywordArgs: Record = {} + const argvalues: Record = {} + let argIndex = 0 for (const arg of node.arguments) { if (arg.type === 'VariableDeclaration') { - keywordArgs[arg.id.name] = arg + const argv = this.processInstruction(scope, arg.init, state) + if ((logger as any).isTraceEnabled()) logger.trace(`arg: ${this.formatScope(argv)}`) + argvalues[arg.id.name] = argv } else { - positionalArgs.push(arg) + const argv = this.processInstruction(scope, arg, state) + if ((logger as any).isTraceEnabled()) logger.trace(`arg: ${this.formatScope(argv)}`) + if (Array.isArray(argv)) { + for (let i = 0; i < argv.length; i++) { + argvalues[argIndex++] = argv[i] + } + } else argvalues[argIndex++] = argv } } - let collectedArgs: any[] - if (fclos.fdef && fclos.fdef.type === 'FunctionDefinition') { - collectedArgs = collectArgsFromArray(fclos.ast.parameters, positionalArgs, keywordArgs, node.arguments.length) - } else { - collectedArgs = node.arguments - } - - for (const arg of collectedArgs) { - const argv = this.processInstruction(scope, arg, state) - if ((logger as any).isTraceEnabled()) logger.trace(`arg: ${this.formatScope(argv)}`) - if (Array.isArray(argv)) argvalues.push(...argv) - else argvalues.push(argv) - } if (argvalues && this.checkerManager) { this.checkerManager.checkAtFunctionCallBefore(this, scope, node, state, { @@ -637,7 +604,7 @@ class PythonAnalyzer extends (Analyzer as any) { fclos = fclos.value[0] } - let argvalues: any[] = [] + let argvalues: Record = [] if (call.arguments) { let same_args = true for (const arg of call.arguments) {