arkanalyzer 1.0.41 → 1.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/arkanalyzer.json +1 -2
- package/lib/Scene.d.ts.map +1 -1
- package/lib/Scene.js +52 -38
- package/lib/callgraph/pointerAnalysis/PTAUtils.d.ts +11 -5
- package/lib/callgraph/pointerAnalysis/PTAUtils.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PTAUtils.js +42 -24
- package/lib/callgraph/pointerAnalysis/Pag.d.ts +6 -11
- package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Pag.js +26 -23
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +11 -63
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PagBuilder.js +72 -499
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +4 -2
- package/lib/callgraph/pointerAnalysis/plugins/ContainerPlugin.d.ts +24 -0
- package/lib/callgraph/pointerAnalysis/plugins/ContainerPlugin.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/plugins/ContainerPlugin.js +167 -0
- package/lib/callgraph/pointerAnalysis/plugins/FunctionPlugin.d.ts +26 -0
- package/lib/callgraph/pointerAnalysis/plugins/FunctionPlugin.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/plugins/FunctionPlugin.js +151 -0
- package/lib/callgraph/pointerAnalysis/plugins/IPagPlugin.d.ts +15 -0
- package/lib/callgraph/pointerAnalysis/plugins/IPagPlugin.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/plugins/IPagPlugin.js +16 -0
- package/lib/callgraph/pointerAnalysis/plugins/PluginManager.d.ts +25 -0
- package/lib/callgraph/pointerAnalysis/plugins/PluginManager.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/plugins/PluginManager.js +66 -0
- package/lib/callgraph/pointerAnalysis/plugins/SdkPlugin.d.ts +37 -0
- package/lib/callgraph/pointerAnalysis/plugins/SdkPlugin.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/plugins/SdkPlugin.js +160 -0
- package/lib/callgraph/pointerAnalysis/plugins/StoragePlugin.d.ts +68 -0
- package/lib/callgraph/pointerAnalysis/plugins/StoragePlugin.d.ts.map +1 -0
- package/lib/callgraph/pointerAnalysis/plugins/StoragePlugin.js +288 -0
- package/lib/core/base/Expr.d.ts +1 -0
- package/lib/core/base/Expr.d.ts.map +1 -1
- package/lib/core/base/Expr.js +9 -0
- package/lib/core/common/DummyMainCreater.js +1 -1
- package/lib/core/common/IRInference.d.ts +1 -1
- package/lib/core/common/IRInference.d.ts.map +1 -1
- package/lib/core/common/IRInference.js +7 -3
- package/lib/core/common/ModelUtils.js +1 -1
- package/lib/core/common/SdkUtils.d.ts +3 -2
- package/lib/core/common/SdkUtils.d.ts.map +1 -1
- package/lib/core/common/SdkUtils.js +30 -30
- package/lib/core/common/TypeInference.d.ts.map +1 -1
- package/lib/core/common/TypeInference.js +7 -5
- package/lib/core/dataflow/DataflowSolver.js +3 -3
- package/lib/core/dataflow/UndefinedVariable.js +2 -2
- package/lib/core/graph/BasicBlock.d.ts.map +1 -1
- package/lib/core/graph/BasicBlock.js +9 -4
- package/lib/core/graph/Cfg.d.ts.map +1 -1
- package/lib/core/graph/Cfg.js +4 -1
- package/lib/core/graph/builder/CfgBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/CfgBuilder.js +4 -4
- package/lib/core/graph/builder/ConditionBuilder.d.ts +2 -1
- package/lib/core/graph/builder/ConditionBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/ConditionBuilder.js +8 -4
- package/lib/core/graph/builder/TrapBuilder.d.ts +19 -1
- package/lib/core/graph/builder/TrapBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/TrapBuilder.js +195 -68
- package/lib/core/model/ArkClass.d.ts.map +1 -1
- package/lib/core/model/ArkClass.js +2 -1
- package/lib/core/model/ArkMethod.d.ts.map +1 -1
- package/lib/core/model/ArkMethod.js +3 -4
- package/lib/core/model/builder/ArkClassBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkClassBuilder.js +24 -20
- package/lib/core/model/builder/ArkImportBuilder.js +28 -25
- package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkMethodBuilder.js +1 -2
- package/lib/core/model/builder/BodyBuilder.js +1 -1
- package/lib/pass/Context.d.ts +47 -0
- package/lib/pass/Context.d.ts.map +1 -0
- package/lib/pass/Context.js +72 -0
- package/lib/pass/Dispatcher.d.ts +102 -0
- package/lib/pass/Dispatcher.d.ts.map +1 -0
- package/lib/pass/Dispatcher.js +202 -0
- package/lib/pass/Pass.d.ts +83 -0
- package/lib/pass/Pass.d.ts.map +1 -0
- package/lib/pass/Pass.js +95 -0
- package/lib/pass/ScenePassMgr.d.ts +73 -0
- package/lib/pass/ScenePassMgr.d.ts.map +1 -0
- package/lib/pass/ScenePassMgr.js +156 -0
- package/lib/pass/validators/Exprs.d.ts +9 -0
- package/lib/pass/validators/Exprs.d.ts.map +1 -0
- package/lib/pass/validators/Exprs.js +40 -0
- package/lib/pass/validators/Models.d.ts +14 -0
- package/lib/pass/validators/Models.d.ts.map +1 -0
- package/lib/pass/validators/Models.js +42 -0
- package/lib/pass/validators/SceneValidator.d.ts +19 -0
- package/lib/pass/validators/SceneValidator.d.ts.map +1 -0
- package/lib/pass/validators/SceneValidator.js +77 -0
- package/lib/pass/validators/Stmts.d.ts +7 -0
- package/lib/pass/validators/Stmts.d.ts.map +1 -0
- package/lib/pass/validators/Stmts.js +36 -0
- package/lib/pass/validators/Validator.d.ts +207 -0
- package/lib/pass/validators/Validator.d.ts.map +1 -0
- package/lib/pass/validators/Validator.js +343 -0
- package/lib/pass/validators/Values.d.ts +7 -0
- package/lib/pass/validators/Values.d.ts.map +1 -0
- package/lib/pass/validators/Values.js +34 -0
- package/lib/save/JsonPrinter.d.ts.map +1 -1
- package/lib/save/JsonPrinter.js +26 -102
- package/lib/save/source/SourceStmt.d.ts +1 -0
- package/lib/save/source/SourceStmt.d.ts.map +1 -1
- package/lib/save/source/SourceStmt.js +5 -8
- package/lib/utils/FileUtils.d.ts.map +1 -1
- package/lib/utils/FileUtils.js +13 -6
- package/lib/utils/ValueAsserts.d.ts +9 -0
- package/lib/utils/ValueAsserts.d.ts.map +1 -0
- package/lib/utils/ValueAsserts.js +89 -0
- package/package.json +2 -2
|
@@ -49,10 +49,10 @@ const Constant_1 = require("../../core/base/Constant");
|
|
|
49
49
|
const Statistics_1 = require("../common/Statistics");
|
|
50
50
|
const Pag_1 = require("./Pag");
|
|
51
51
|
const TSConst_1 = require("../../core/common/TSConst");
|
|
52
|
-
const PTAUtils_1 = require("./PTAUtils");
|
|
53
52
|
const PointerAnalysisConfig_1 = require("./PointerAnalysisConfig");
|
|
54
53
|
const Context_1 = require("./context/Context");
|
|
55
54
|
const ContextSelector_1 = require("./context/ContextSelector");
|
|
55
|
+
const PluginManager_1 = require("./plugins/PluginManager");
|
|
56
56
|
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'PTA');
|
|
57
57
|
class CSFuncID {
|
|
58
58
|
constructor(cid, fid) {
|
|
@@ -69,14 +69,10 @@ class PagBuilder {
|
|
|
69
69
|
this.staticField2UniqInstanceMap = new Map();
|
|
70
70
|
this.instanceField2UniqInstanceMap = new Map();
|
|
71
71
|
this.sdkMethodReturnValueMap = new Map();
|
|
72
|
-
// record the SDK API param, and create fake Values
|
|
73
|
-
this.methodParamValueMap = new Map();
|
|
74
|
-
this.fakeSdkMethodParamDeclaringStmt = new Stmt_1.ArkAssignStmt(new Local_1.Local(''), new Local_1.Local(''));
|
|
75
72
|
this.funcHandledThisRound = new Set();
|
|
76
73
|
this.updatedNodesThisRound = new Map();
|
|
77
74
|
this.singletonFuncMap = new Map();
|
|
78
75
|
this.globalThisValue = new Local_1.Local(TSConst_1.GLOBAL_THIS_NAME);
|
|
79
|
-
this.storagePropertyMap = new Map();
|
|
80
76
|
this.externalScopeVariableMap = new Map();
|
|
81
77
|
this.retriggerNodesList = new Set();
|
|
82
78
|
this.pag = p;
|
|
@@ -85,6 +81,7 @@ class PagBuilder {
|
|
|
85
81
|
this.funcPags = new Map();
|
|
86
82
|
this.scene = s;
|
|
87
83
|
this.pagStat = new Statistics_1.PAGStat();
|
|
84
|
+
this.pluginManager = new PluginManager_1.PluginManager(p, this, cg);
|
|
88
85
|
let kLimit = config.kLimit;
|
|
89
86
|
switch (config.contextType) {
|
|
90
87
|
case PointerAnalysisConfig_1.ContextType.CallSite:
|
|
@@ -159,8 +156,8 @@ class PagBuilder {
|
|
|
159
156
|
}
|
|
160
157
|
let cfg = arkMethod.getCfg();
|
|
161
158
|
if (!cfg) {
|
|
162
|
-
|
|
163
|
-
return
|
|
159
|
+
// build as sdk method
|
|
160
|
+
return this.pluginManager.processSDKFuncPag(funcID, arkMethod).handled;
|
|
164
161
|
}
|
|
165
162
|
logger.trace(`[build FuncPag] ${arkMethod.getSignature().toString()}`);
|
|
166
163
|
let fpag = new Pag_1.FuncPag();
|
|
@@ -228,18 +225,9 @@ class PagBuilder {
|
|
|
228
225
|
}
|
|
229
226
|
}
|
|
230
227
|
/**
|
|
231
|
-
*
|
|
228
|
+
* process Method level analysis only
|
|
232
229
|
*/
|
|
233
|
-
|
|
234
|
-
// check if SDK method
|
|
235
|
-
let cgNode = this.cg.getNode(funcID);
|
|
236
|
-
if (!cgNode.isSdkMethod()) {
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
let paramArr = this.createDummyParamValue(funcID);
|
|
240
|
-
this.methodParamValueMap.set(funcID, paramArr);
|
|
241
|
-
}
|
|
242
|
-
createDummyParamValue(funcID, type = 1) {
|
|
230
|
+
createDummyParamValue(funcID) {
|
|
243
231
|
let arkMethod = this.cg.getArkMethodByFuncID(funcID);
|
|
244
232
|
if (!arkMethod) {
|
|
245
233
|
return new Map();
|
|
@@ -249,26 +237,16 @@ class PagBuilder {
|
|
|
249
237
|
return new Map();
|
|
250
238
|
}
|
|
251
239
|
let paramArr = new Map();
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
else if (type === 1) {
|
|
265
|
-
// Local
|
|
266
|
-
args.forEach((arg, index) => {
|
|
267
|
-
let argInstance = new Local_1.Local(arg.getName(), arg.getType());
|
|
268
|
-
argInstance.setDeclaringStmt(this.fakeSdkMethodParamDeclaringStmt);
|
|
269
|
-
paramArr.set(index, argInstance);
|
|
270
|
-
});
|
|
271
|
-
}
|
|
240
|
+
// heapObj
|
|
241
|
+
args.forEach((arg, index) => {
|
|
242
|
+
let paramType = arg.getType();
|
|
243
|
+
if (!(paramType instanceof Type_1.ClassType)) {
|
|
244
|
+
return;
|
|
245
|
+
// TODO: support more type
|
|
246
|
+
}
|
|
247
|
+
let argInstance = new Expr_1.ArkNewExpr(paramType);
|
|
248
|
+
paramArr.set(index, argInstance);
|
|
249
|
+
});
|
|
272
250
|
return paramArr;
|
|
273
251
|
}
|
|
274
252
|
createDummyParamPagNodes(value, funcID) {
|
|
@@ -278,7 +256,7 @@ class PagBuilder {
|
|
|
278
256
|
return paramPagNodes;
|
|
279
257
|
}
|
|
280
258
|
value.forEach((v, index) => {
|
|
281
|
-
let paramArkExprNode = this.pag.getOrNewNode(Context_1.DUMMY_CID, v
|
|
259
|
+
let paramArkExprNode = this.pag.getOrNewNode(Context_1.DUMMY_CID, v);
|
|
282
260
|
paramPagNodes.set(index, paramArkExprNode.getID());
|
|
283
261
|
});
|
|
284
262
|
return paramPagNodes;
|
|
@@ -311,7 +289,7 @@ class PagBuilder {
|
|
|
311
289
|
let paramNodes;
|
|
312
290
|
let paramRefIndex = 0;
|
|
313
291
|
if (this.scale === PointerAnalysisConfig_1.PtaAnalysisScale.MethodLevel) {
|
|
314
|
-
paramNodes = this.createDummyParamPagNodes(this.createDummyParamValue(funcID
|
|
292
|
+
paramNodes = this.createDummyParamPagNodes(this.createDummyParamValue(funcID), funcID);
|
|
315
293
|
}
|
|
316
294
|
for (let e of inEdges) {
|
|
317
295
|
let srcPagNode = this.getOrNewPagNode(cid, e.src, e.stmt);
|
|
@@ -334,17 +312,20 @@ class PagBuilder {
|
|
|
334
312
|
}
|
|
335
313
|
/// add Copy edges interprocedural
|
|
336
314
|
addCallsEdgesFromFuncPag(funcPag, cid) {
|
|
337
|
-
var _a, _b;
|
|
338
315
|
for (let cs of funcPag.getNormalCallSites()) {
|
|
339
316
|
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
340
|
-
|
|
341
|
-
let
|
|
317
|
+
const calleeFuncID = cs.getCalleeFuncID();
|
|
318
|
+
let calleeCid = this.ctxSelector.selectContext(cid, cs, ContextSelector_1.emptyID, calleeFuncID);
|
|
319
|
+
let calleeCGNode = this.cg.getNode(calleeFuncID);
|
|
342
320
|
if (this.scale === PointerAnalysisConfig_1.PtaAnalysisScale.MethodLevel) {
|
|
343
321
|
this.addStaticPagCallReturnEdge(cs, cid, calleeCid);
|
|
344
322
|
}
|
|
345
|
-
//
|
|
346
|
-
|
|
347
|
-
|
|
323
|
+
// Storage Plugin, SDK Plugin
|
|
324
|
+
const pluginResult = this.pluginManager.processCallSite(cs, cid, ContextSelector_1.emptyID, this.cg);
|
|
325
|
+
if (pluginResult.handled) {
|
|
326
|
+
logger.debug(`[buildFuncPag] plugin handled call site ${cs.callStmt.toString()}`);
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
348
329
|
this.addStaticPagCallEdge(cs, cid, calleeCid);
|
|
349
330
|
}
|
|
350
331
|
// Add edge to thisRef for special calls
|
|
@@ -357,7 +338,13 @@ class PagBuilder {
|
|
|
357
338
|
logger.error(`constructor or intrinsic func is static ${ivkExpr.toString()}`);
|
|
358
339
|
}
|
|
359
340
|
}
|
|
360
|
-
|
|
341
|
+
const callerMethod = this.cg.getArkMethodByFuncID(cs.callerFuncID);
|
|
342
|
+
const calleeMethod = this.cg.getArkMethodByFuncID(calleeFuncID);
|
|
343
|
+
if (!callerMethod || !calleeMethod) {
|
|
344
|
+
logger.error(`can not find caller or callee method by funcID ${cs.callerFuncID} ${calleeFuncID}`);
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
this.cg.addDirectOrSpecialCallEdge(callerMethod.getSignature(), calleeMethod.getSignature(), cs.callStmt);
|
|
361
348
|
}
|
|
362
349
|
return true;
|
|
363
350
|
}
|
|
@@ -456,18 +443,18 @@ class PagBuilder {
|
|
|
456
443
|
return srcNodes;
|
|
457
444
|
}
|
|
458
445
|
let staticCS = this.cg.getCallSiteManager().cloneCallSiteFromDyn(cs, dstCGNode.getID());
|
|
459
|
-
let calleeCid = this.ctxSelector.selectContext(cid, staticCS, baseClassPTNode, dstCGNode.getID());
|
|
460
446
|
if (this.scale === PointerAnalysisConfig_1.PtaAnalysisScale.MethodLevel) {
|
|
461
|
-
srcNodes.push(...this.addStaticPagCallReturnEdge(staticCS,
|
|
447
|
+
srcNodes.push(...this.addStaticPagCallReturnEdge(staticCS, cid, baseClassPTNode));
|
|
462
448
|
continue;
|
|
463
449
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
450
|
+
// Storage Plugin, SDK Plugin, Function Plugin, Container Plugin
|
|
451
|
+
const pluginResult = this.pluginManager.processCallSite(staticCS, cid, baseClassPTNode, this.cg);
|
|
452
|
+
if (pluginResult.handled) {
|
|
453
|
+
logger.debug(`[buildDynamicCallEdge] plugin handled call site ${cs.callStmt.toString()}`);
|
|
454
|
+
srcNodes.push(...pluginResult.srcNodes);
|
|
455
|
+
continue;
|
|
470
456
|
}
|
|
457
|
+
srcNodes.push(...this.processNormalMethodPagCallEdge(staticCS, cid, baseClassPTNode));
|
|
471
458
|
}
|
|
472
459
|
return srcNodes;
|
|
473
460
|
}
|
|
@@ -476,6 +463,7 @@ class PagBuilder {
|
|
|
476
463
|
* handle both PtrInvokeExpr and InstanceInvokeExpr
|
|
477
464
|
*/
|
|
478
465
|
getDynamicCallee(ptNode, value, ivkExpr, cs) {
|
|
466
|
+
var _a, _b;
|
|
479
467
|
let callee = [];
|
|
480
468
|
if (ptNode instanceof Pag_1.PagFuncNode) {
|
|
481
469
|
// function ptr invoke
|
|
@@ -492,20 +480,22 @@ class PagBuilder {
|
|
|
492
480
|
if (!(value instanceof Expr_1.ArkNewExpr || value instanceof Expr_1.ArkNewArrayExpr)) {
|
|
493
481
|
return callee;
|
|
494
482
|
}
|
|
495
|
-
let tempCallee;
|
|
496
483
|
// try to get callee by MethodSignature
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
let cls;
|
|
501
|
-
cls = this.scene.getClass(clsSig);
|
|
502
|
-
while (!tempCallee && cls) {
|
|
503
|
-
tempCallee = cls.getMethodWithName(calleeName);
|
|
504
|
-
cls = cls.getSuperClass();
|
|
505
|
-
}
|
|
506
|
-
if (!tempCallee) {
|
|
507
|
-
tempCallee = this.scene.getMethod(ivkExpr.getMethodSignature());
|
|
484
|
+
const getClassSignature = (value) => {
|
|
485
|
+
if (value instanceof Expr_1.ArkNewExpr) {
|
|
486
|
+
return value.getType().getClassSignature();
|
|
508
487
|
}
|
|
488
|
+
return this.scene.getSdkGlobal('Array').getSignature();
|
|
489
|
+
};
|
|
490
|
+
const clsSig = getClassSignature(value);
|
|
491
|
+
let cls = this.scene.getClass(clsSig);
|
|
492
|
+
let tempCallee;
|
|
493
|
+
while (!tempCallee && cls) {
|
|
494
|
+
tempCallee = (_a = cls.getMethodWithName(calleeName)) !== null && _a !== void 0 ? _a : undefined;
|
|
495
|
+
cls = cls.getSuperClass();
|
|
496
|
+
}
|
|
497
|
+
if (!tempCallee) {
|
|
498
|
+
tempCallee = (_b = this.scene.getMethod(ivkExpr.getMethodSignature())) !== null && _b !== void 0 ? _b : undefined;
|
|
509
499
|
}
|
|
510
500
|
if (!tempCallee && cs.args) {
|
|
511
501
|
// while pts has {o_1, o_2} and invoke expr represents a method that only {o_1} has
|
|
@@ -524,11 +514,12 @@ class PagBuilder {
|
|
|
524
514
|
}
|
|
525
515
|
return callee;
|
|
526
516
|
}
|
|
527
|
-
processNormalMethodPagCallEdge(staticCS, cid,
|
|
517
|
+
processNormalMethodPagCallEdge(staticCS, cid, baseClassPTNode) {
|
|
528
518
|
let srcNodes = [];
|
|
529
519
|
let ivkExpr = staticCS.callStmt.getInvokeExpr();
|
|
530
520
|
let ptNode = this.pag.getNode(baseClassPTNode);
|
|
531
521
|
let dstCGNode = this.cg.getNode(staticCS.calleeFuncID);
|
|
522
|
+
let calleeCid = this.ctxSelector.selectContext(cid, staticCS, baseClassPTNode, dstCGNode.getID());
|
|
532
523
|
let callee = this.cg.getArkMethodByFuncID(staticCS.calleeFuncID);
|
|
533
524
|
// Dynamic call, Ptr call, normal SDK call
|
|
534
525
|
srcNodes.push(...this.addStaticPagCallEdge(staticCS, cid, calleeCid, ptNode));
|
|
@@ -552,126 +543,6 @@ class PagBuilder {
|
|
|
552
543
|
}
|
|
553
544
|
return srcNodes;
|
|
554
545
|
}
|
|
555
|
-
/**
|
|
556
|
-
* include container API, Function API
|
|
557
|
-
*/
|
|
558
|
-
processBuiltInMethodPagCallEdge(staticCS, cid, calleeCid, baseClassPTNode) {
|
|
559
|
-
let srcNodes = [];
|
|
560
|
-
let ivkExpr = staticCS.callStmt.getInvokeExpr();
|
|
561
|
-
let callee = this.scene.getMethod(ivkExpr.getMethodSignature());
|
|
562
|
-
let realCallee = this.cg.getArkMethodByFuncID(staticCS.calleeFuncID);
|
|
563
|
-
if (!callee) {
|
|
564
|
-
return srcNodes;
|
|
565
|
-
}
|
|
566
|
-
let builtInType = (0, PTAUtils_1.getBuiltInApiType)(callee.getSignature());
|
|
567
|
-
if (builtInType === PTAUtils_1.BuiltApiType.NotBuiltIn || !realCallee) {
|
|
568
|
-
return srcNodes;
|
|
569
|
-
}
|
|
570
|
-
switch (builtInType) {
|
|
571
|
-
case PTAUtils_1.BuiltApiType.SetAdd:
|
|
572
|
-
case PTAUtils_1.BuiltApiType.MapSet:
|
|
573
|
-
this.processContainerPagCallEdge(staticCS, cid, baseClassPTNode, builtInType);
|
|
574
|
-
break;
|
|
575
|
-
case PTAUtils_1.BuiltApiType.FunctionCall:
|
|
576
|
-
/**
|
|
577
|
-
* set this and param
|
|
578
|
-
* function.call(thisArg, arg1, arg2, ...)
|
|
579
|
-
*/
|
|
580
|
-
this.handleFunctionCall(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode);
|
|
581
|
-
break;
|
|
582
|
-
case PTAUtils_1.BuiltApiType.FunctionApply:
|
|
583
|
-
/**
|
|
584
|
-
* set this, resolve array param
|
|
585
|
-
* function.apply(thisArg, [argsArray])
|
|
586
|
-
*/
|
|
587
|
-
this.handleFunctionApply(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode);
|
|
588
|
-
break;
|
|
589
|
-
case PTAUtils_1.BuiltApiType.FunctionBind:
|
|
590
|
-
/**
|
|
591
|
-
* clone the function node and add the this pointer, origin callSite, args offset to it
|
|
592
|
-
* let f = function.bind(thisArg, arg1, arg2, ...)
|
|
593
|
-
* f();
|
|
594
|
-
*/
|
|
595
|
-
this.handleFunctionBind(staticCS, cid, baseClassPTNode, srcNodes);
|
|
596
|
-
break;
|
|
597
|
-
default:
|
|
598
|
-
}
|
|
599
|
-
return srcNodes;
|
|
600
|
-
}
|
|
601
|
-
processContainerPagCallEdge(cs, cid, baseClassPTNode, type) {
|
|
602
|
-
let srcNodes = [];
|
|
603
|
-
let calleeNode = this.cg.getNode(cs.calleeFuncID);
|
|
604
|
-
let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
|
|
605
|
-
let ptNode = this.pag.getNode(baseClassPTNode);
|
|
606
|
-
if (!calleeMethod || !(ptNode instanceof Pag_1.PagNewContainerExprNode)) {
|
|
607
|
-
return srcNodes;
|
|
608
|
-
}
|
|
609
|
-
let containerValue = cs.callStmt.getInvokeExpr().getBase();
|
|
610
|
-
const containerValueProcess = (argIndex) => {
|
|
611
|
-
let srcNode = this.pag.getOrNewNode(cid, cs.args[argIndex], cs.callStmt);
|
|
612
|
-
let realContainerFieldPagNode = this.pag.getOrClonePagContainerFieldNode(baseClassPTNode, undefined, containerValue);
|
|
613
|
-
if (realContainerFieldPagNode) {
|
|
614
|
-
// In some cases, the value of a variable of array type may not be an explicit array object,
|
|
615
|
-
// and the value of `realContainerFieldPagNode` will be undefined.
|
|
616
|
-
this.pag.addPagEdge(srcNode, realContainerFieldPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
617
|
-
srcNodes.push(srcNode.getID());
|
|
618
|
-
}
|
|
619
|
-
};
|
|
620
|
-
if (type === PTAUtils_1.BuiltApiType.SetAdd) {
|
|
621
|
-
containerValueProcess(0);
|
|
622
|
-
}
|
|
623
|
-
else if (type === PTAUtils_1.BuiltApiType.MapSet) {
|
|
624
|
-
containerValueProcess(1);
|
|
625
|
-
}
|
|
626
|
-
return srcNodes;
|
|
627
|
-
}
|
|
628
|
-
handleFunctionCall(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode) {
|
|
629
|
-
this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID));
|
|
630
|
-
srcNodes.push(...this.addCallParamPagEdge(realCallee, staticCS.args, staticCS.callStmt, cid, calleeCid, 1));
|
|
631
|
-
this.addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid);
|
|
632
|
-
}
|
|
633
|
-
handleFunctionApply(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode) {
|
|
634
|
-
this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID));
|
|
635
|
-
let callerMethod = this.cg.getArkMethodByFuncID(staticCS.callerFuncID);
|
|
636
|
-
if (!callerMethod) {
|
|
637
|
-
throw new Error('Cannot get caller method');
|
|
638
|
-
}
|
|
639
|
-
let argsRealValues = this.transferArrayValues(callerMethod, staticCS.args[1]);
|
|
640
|
-
srcNodes.push(...this.addCallParamPagEdge(realCallee, argsRealValues, staticCS.callStmt, cid, calleeCid, 0));
|
|
641
|
-
this.addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid);
|
|
642
|
-
}
|
|
643
|
-
handleFunctionBind(staticCS, cid, baseClassPTNode, srcNodes) {
|
|
644
|
-
let srcNode = this.pag.getOrClonePagFuncNode(baseClassPTNode);
|
|
645
|
-
if (!srcNode) {
|
|
646
|
-
return;
|
|
647
|
-
}
|
|
648
|
-
this.setFunctionThisPt(staticCS, srcNode, cid);
|
|
649
|
-
let dstNode = this.getOrNewPagNode(cid, staticCS.callStmt.getLeftOp());
|
|
650
|
-
this.pag.addPagEdge(srcNode, dstNode, Pag_1.PagEdgeKind.Copy, staticCS.callStmt);
|
|
651
|
-
srcNodes.push(srcNode.getID());
|
|
652
|
-
srcNode.setCS(staticCS);
|
|
653
|
-
srcNode.setArgsOffset(1);
|
|
654
|
-
srcNode.setOriginCid(cid);
|
|
655
|
-
}
|
|
656
|
-
addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid) {
|
|
657
|
-
if (!(staticCS.args[0] instanceof Constant_1.NullConstant) && !realCallee.isStatic()) {
|
|
658
|
-
let srcNodeID = this.addThisRefCallEdge(cid, staticCS.args[0], realCallee, calleeCid, staticCS.callerFuncID);
|
|
659
|
-
if (srcNodeID !== -1) {
|
|
660
|
-
srcNodes.push(srcNodeID);
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
setFunctionThisPt(staticCS, srcNode, cid) {
|
|
665
|
-
let thisLocal = staticCS.args[0];
|
|
666
|
-
if (!(thisLocal instanceof Local_1.Local)) {
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
let thisInstanceLocal = this.getRealThisLocal(thisLocal, staticCS.callerFuncID);
|
|
670
|
-
let baseThisNode = this.pag.getOrNewNode(cid, thisInstanceLocal);
|
|
671
|
-
for (let pt of baseThisNode.getPointTo()) {
|
|
672
|
-
srcNode.setThisPt(pt);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
546
|
handleUnkownDynamicCall(cs, cid) {
|
|
676
547
|
var _a;
|
|
677
548
|
let srcNodes = [];
|
|
@@ -703,13 +574,6 @@ class PagBuilder {
|
|
|
703
574
|
if (!callerNode) {
|
|
704
575
|
throw new Error('Can not get caller method node');
|
|
705
576
|
}
|
|
706
|
-
if (this.processStorage(cs, dstCGNode, cid)) {
|
|
707
|
-
if (ivkExpr.getArgs().length !== 0) {
|
|
708
|
-
// for AppStorage.set() instance invoke, add obj to reanalyze list
|
|
709
|
-
let argsNode = this.pag.getOrNewNode(cid, cs.args[0]);
|
|
710
|
-
srcNodes.push(argsNode.getID());
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
577
|
logger.warn(`\tAdd call edge of unknown call ${callee.getSignature().toString()}`);
|
|
714
578
|
this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt);
|
|
715
579
|
if (!this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
|
|
@@ -809,7 +673,7 @@ class PagBuilder {
|
|
|
809
673
|
return srcNodes;
|
|
810
674
|
}
|
|
811
675
|
if (calleeNode.isSdkMethod()) {
|
|
812
|
-
|
|
676
|
+
logger.error(`SDK method ${calleeMethod.getSignature().toString()} shoule be handled by plugin`);
|
|
813
677
|
return srcNodes;
|
|
814
678
|
}
|
|
815
679
|
if (!calleeMethod.getCfg()) {
|
|
@@ -827,16 +691,17 @@ class PagBuilder {
|
|
|
827
691
|
argsOffset = (_c = ptNode.getArgsOffset()) !== null && _c !== void 0 ? _c : 0;
|
|
828
692
|
callerCid = (_d = ptNode.getOriginCid()) !== null && _d !== void 0 ? _d : callerCid;
|
|
829
693
|
}
|
|
830
|
-
srcNodes.push(...this.addCallParamPagEdge(calleeMethod, realArgs, cs
|
|
694
|
+
srcNodes.push(...this.addCallParamPagEdge(calleeMethod, realArgs, cs, callerCid, calleeCid, argsOffset));
|
|
831
695
|
srcNodes.push(...this.addCallReturnPagEdge(calleeMethod, cs.callStmt, callerCid, calleeCid));
|
|
832
696
|
return srcNodes;
|
|
833
697
|
}
|
|
834
698
|
/**
|
|
835
699
|
* only process the param PAG edge for invoke stmt
|
|
836
700
|
*/
|
|
837
|
-
addCallParamPagEdge(calleeMethod, args,
|
|
838
|
-
var _a;
|
|
839
|
-
let
|
|
701
|
+
addCallParamPagEdge(calleeMethod, args, cs, callerCid, calleeCid, offset) {
|
|
702
|
+
var _a, _b;
|
|
703
|
+
let callStmt = cs.callStmt;
|
|
704
|
+
const params = (_a = this.pluginManager.getSDKParamValue(calleeMethod)) !== null && _a !== void 0 ? _a : calleeMethod
|
|
840
705
|
.getCfg()
|
|
841
706
|
.getStmts()
|
|
842
707
|
.filter(stmt => stmt instanceof Stmt_1.ArkAssignStmt && stmt.getRightOp() instanceof Ref_1.ArkParameterRef)
|
|
@@ -848,7 +713,7 @@ class PagBuilder {
|
|
|
848
713
|
* cs.args is anonymous method local, will have only 1 parameter
|
|
849
714
|
* but inside foreach will have >= 1 parameters
|
|
850
715
|
*/
|
|
851
|
-
if (((
|
|
716
|
+
if (((_b = callStmt.getInvokeExpr()) === null || _b === void 0 ? void 0 : _b.getMethodSignature().getMethodSubSignature().getMethodName()) === 'forEach') {
|
|
852
717
|
srcNodes.push(...this.addForeachParamPagEdge(callerCid, calleeCid, callStmt, params));
|
|
853
718
|
return srcNodes;
|
|
854
719
|
}
|
|
@@ -931,38 +796,20 @@ class PagBuilder {
|
|
|
931
796
|
}
|
|
932
797
|
return srcNodes;
|
|
933
798
|
}
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
799
|
+
/**
|
|
800
|
+
* for method level call graph, add return edge
|
|
801
|
+
*/
|
|
802
|
+
addStaticPagCallReturnEdge(cs, cid, baseClassPTNode) {
|
|
938
803
|
let srcNodes = [];
|
|
939
804
|
// Add reachable
|
|
940
805
|
let calleeNode = this.cg.getNode(cs.calleeFuncID);
|
|
941
806
|
let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
|
|
807
|
+
let calleeCid = this.ctxSelector.selectContext(cid, cs, baseClassPTNode, cs.calleeFuncID);
|
|
942
808
|
if (!calleeMethod) {
|
|
943
809
|
// TODO: check if nodes need to delete
|
|
944
810
|
return srcNodes;
|
|
945
811
|
}
|
|
946
|
-
srcNodes.push(...this.addSDKMethodReturnPagEdge(cs,
|
|
947
|
-
return srcNodes;
|
|
948
|
-
}
|
|
949
|
-
addSDKMethodPagCallEdge(cs, callerCid, calleeCid) {
|
|
950
|
-
let srcNodes = [];
|
|
951
|
-
let calleeNode = this.cg.getNode(cs.calleeFuncID);
|
|
952
|
-
let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
|
|
953
|
-
if (!calleeMethod) {
|
|
954
|
-
return srcNodes;
|
|
955
|
-
}
|
|
956
|
-
let methodType = (0, PTAUtils_1.getBuiltInApiType)(calleeMethod.getSignature());
|
|
957
|
-
// block the container SDK
|
|
958
|
-
if (methodType === PTAUtils_1.BuiltApiType.SetAdd || PTAUtils_1.BuiltApiType.MapSet) {
|
|
959
|
-
return srcNodes;
|
|
960
|
-
}
|
|
961
|
-
if (!this.methodParamValueMap.has(calleeNode.getID())) {
|
|
962
|
-
this.buildSDKFuncPag(calleeNode.getID());
|
|
963
|
-
}
|
|
964
|
-
srcNodes.push(...this.addSDKMethodReturnPagEdge(cs, callerCid, calleeCid, calleeMethod));
|
|
965
|
-
srcNodes.push(...this.addSDKMethodParamPagEdge(cs, callerCid, calleeCid, calleeNode.getID()));
|
|
812
|
+
srcNodes.push(...this.addSDKMethodReturnPagEdge(cs, cid, calleeCid, calleeMethod)); // TODO: ???? why sdk
|
|
966
813
|
return srcNodes;
|
|
967
814
|
}
|
|
968
815
|
addSDKMethodReturnPagEdge(cs, callerCid, calleeCid, calleeMethod) {
|
|
@@ -990,52 +837,6 @@ class PagBuilder {
|
|
|
990
837
|
srcNodes.push(srcPagNode.getID());
|
|
991
838
|
return srcNodes;
|
|
992
839
|
}
|
|
993
|
-
addSDKMethodParamPagEdge(cs, callerCid, calleeCid, funcID) {
|
|
994
|
-
var _a, _b;
|
|
995
|
-
let argNum = (_a = cs.args) === null || _a === void 0 ? void 0 : _a.length;
|
|
996
|
-
let srcNodes = [];
|
|
997
|
-
if (!argNum) {
|
|
998
|
-
return srcNodes;
|
|
999
|
-
}
|
|
1000
|
-
// add args to parameters edges
|
|
1001
|
-
for (let i = 0; i < argNum; i++) {
|
|
1002
|
-
let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b[i];
|
|
1003
|
-
let paramValue;
|
|
1004
|
-
if (arg instanceof Local_1.Local && arg.getType() instanceof Type_1.FunctionType) {
|
|
1005
|
-
// TODO: cannot find value
|
|
1006
|
-
paramValue = this.methodParamValueMap.get(funcID).get(i);
|
|
1007
|
-
}
|
|
1008
|
-
else {
|
|
1009
|
-
continue;
|
|
1010
|
-
}
|
|
1011
|
-
if (!(arg && paramValue)) {
|
|
1012
|
-
continue;
|
|
1013
|
-
}
|
|
1014
|
-
// Get or create new PAG node for argument and parameter
|
|
1015
|
-
let srcPagNode = this.getOrNewPagNode(callerCid, arg, cs.callStmt);
|
|
1016
|
-
let dstPagNode = this.getOrNewPagNode(calleeCid, paramValue, cs.callStmt);
|
|
1017
|
-
if (dstPagNode instanceof Pag_1.PagLocalNode) {
|
|
1018
|
-
// set the fake param Value in PagLocalNode
|
|
1019
|
-
/**
|
|
1020
|
-
* TODO: !!!
|
|
1021
|
-
* some API param is in the form of anonymous method:
|
|
1022
|
-
* component/common.d.ts
|
|
1023
|
-
* declare function animateTo(value: AnimateParam, event: () => void): void;
|
|
1024
|
-
*
|
|
1025
|
-
* this param fake Value will create PagFuncNode rather than PagLocalNode
|
|
1026
|
-
* when this API is called, the anonymous method pointer will not be able to pass into the fake Value PagNode
|
|
1027
|
-
*/
|
|
1028
|
-
dstPagNode.setSdkParam();
|
|
1029
|
-
let sdkParamInvokeStmt = new Stmt_1.ArkInvokeStmt(new Expr_1.ArkPtrInvokeExpr(arg.getType().getMethodSignature(), paramValue, []));
|
|
1030
|
-
// create new DynCallSite
|
|
1031
|
-
let sdkParamCallSite = this.cg.getCallSiteManager().newDynCallSite(sdkParamInvokeStmt, undefined, undefined, funcID);
|
|
1032
|
-
dstPagNode.addRelatedDynCallSite(sdkParamCallSite);
|
|
1033
|
-
}
|
|
1034
|
-
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
1035
|
-
srcNodes.push(srcPagNode.getID());
|
|
1036
|
-
}
|
|
1037
|
-
return srcNodes;
|
|
1038
|
-
}
|
|
1039
840
|
getOrNewPagNode(cid, v, s) {
|
|
1040
841
|
// globalThis process can not be removed while all `globalThis` ref is the same Value
|
|
1041
842
|
if (v instanceof Local_1.Local && v.getName() === TSConst_1.GLOBAL_THIS_NAME && v.getDeclaringStmt() == null) {
|
|
@@ -1050,63 +851,6 @@ class PagBuilder {
|
|
|
1050
851
|
getOrNewGlobalThisNode(cid) {
|
|
1051
852
|
return this.pag.getOrNewNode(cid, this.getGlobalThisValue());
|
|
1052
853
|
}
|
|
1053
|
-
/**
|
|
1054
|
-
* search the storage map to get propertyNode with given storage and propertyFieldName
|
|
1055
|
-
* @param storage storage type: AppStorage, LocalStorage etc.
|
|
1056
|
-
* @param propertyName string property key
|
|
1057
|
-
* @returns propertyNode: PagLocalNode
|
|
1058
|
-
*/
|
|
1059
|
-
getOrNewPropertyNode(storage, propertyName, stmt) {
|
|
1060
|
-
let propertyNode = this.getPropertyNode(storage, propertyName, stmt);
|
|
1061
|
-
if (propertyNode) {
|
|
1062
|
-
return propertyNode;
|
|
1063
|
-
}
|
|
1064
|
-
let storageMap = this.storagePropertyMap.get(storage);
|
|
1065
|
-
let propertyLocal = new Local_1.Local(propertyName);
|
|
1066
|
-
storageMap.set(propertyName, propertyLocal);
|
|
1067
|
-
this.storagePropertyMap.set(storage, storageMap);
|
|
1068
|
-
return this.getOrNewPagNode(-1, propertyLocal, stmt);
|
|
1069
|
-
}
|
|
1070
|
-
getPropertyNode(storage, propertyName, stmt) {
|
|
1071
|
-
let storageMap = this.storagePropertyMap.get(storage);
|
|
1072
|
-
let propertyLocal;
|
|
1073
|
-
if (!storageMap) {
|
|
1074
|
-
storageMap = new Map();
|
|
1075
|
-
this.storagePropertyMap.set(storage, storageMap);
|
|
1076
|
-
}
|
|
1077
|
-
if (storageMap.has(propertyName)) {
|
|
1078
|
-
propertyLocal = storageMap.get(propertyName);
|
|
1079
|
-
}
|
|
1080
|
-
if (propertyLocal) {
|
|
1081
|
-
return this.getOrNewPagNode(-1, propertyLocal, stmt);
|
|
1082
|
-
}
|
|
1083
|
-
return undefined;
|
|
1084
|
-
}
|
|
1085
|
-
/**
|
|
1086
|
-
* add PagEdge
|
|
1087
|
-
* @param edgeKind: edge kind differs from API
|
|
1088
|
-
* @param propertyNode: PAG node created by protpertyName
|
|
1089
|
-
* @param obj: heapObj stored with Storage API
|
|
1090
|
-
*/
|
|
1091
|
-
addPropertyLinkEdge(propertyNode, storageObj, cid, stmt, edgeKind) {
|
|
1092
|
-
if (!(storageObj.getType() instanceof Type_1.ClassType)) {
|
|
1093
|
-
return false;
|
|
1094
|
-
}
|
|
1095
|
-
if (edgeKind === Pag_1.StorageLinkEdgeType.Property2Local) {
|
|
1096
|
-
// propertyNode --> objNode
|
|
1097
|
-
this.pag.addPagEdge(propertyNode, this.pag.getOrNewNode(cid, storageObj), Pag_1.PagEdgeKind.Copy, stmt);
|
|
1098
|
-
}
|
|
1099
|
-
else if (edgeKind === Pag_1.StorageLinkEdgeType.Local2Property) {
|
|
1100
|
-
// propertyNode <-- objNode
|
|
1101
|
-
this.pag.addPagEdge(this.pag.getOrNewNode(cid, storageObj), propertyNode, Pag_1.PagEdgeKind.Copy, stmt);
|
|
1102
|
-
}
|
|
1103
|
-
else if (edgeKind === Pag_1.StorageLinkEdgeType.TwoWay) {
|
|
1104
|
-
// propertyNode <-> objNode
|
|
1105
|
-
this.pag.addPagEdge(propertyNode, this.pag.getOrNewNode(cid, storageObj), Pag_1.PagEdgeKind.Copy, stmt);
|
|
1106
|
-
this.pag.addPagEdge(this.pag.getOrNewNode(cid, storageObj), propertyNode, Pag_1.PagEdgeKind.Copy, stmt);
|
|
1107
|
-
}
|
|
1108
|
-
return true;
|
|
1109
|
-
}
|
|
1110
854
|
/*
|
|
1111
855
|
* In ArkIR, ArkField has multiple instances for each stmt which use it
|
|
1112
856
|
* But the unique one is needed for pointer analysis
|
|
@@ -1247,158 +991,6 @@ class PagBuilder {
|
|
|
1247
991
|
}
|
|
1248
992
|
return Pag_1.PagEdgeKind.Unknown;
|
|
1249
993
|
}
|
|
1250
|
-
/**
|
|
1251
|
-
* process Storage API
|
|
1252
|
-
* @returns boolean: check if the cs represent a Storage API, no matter the API will success or fail
|
|
1253
|
-
*/
|
|
1254
|
-
processStorage(cs, calleeCGNode, cid) {
|
|
1255
|
-
let storageName = calleeCGNode.getMethod().getDeclaringClassSignature().getClassName();
|
|
1256
|
-
let storageType = this.getStorageType(storageName, cs, cid);
|
|
1257
|
-
// TODO: add other storages
|
|
1258
|
-
if (storageType === Pag_1.StorageType.APP_STORAGE) {
|
|
1259
|
-
let calleeName = calleeCGNode.getMethod().getMethodSubSignature().getMethodName();
|
|
1260
|
-
// TODO: complete AppStorage API
|
|
1261
|
-
if (calleeName === 'setOrCreate') {
|
|
1262
|
-
this.processStorageSetOrCreate(cs, cid);
|
|
1263
|
-
}
|
|
1264
|
-
else if (calleeName === 'link') {
|
|
1265
|
-
this.processStorageLink(cs, cid);
|
|
1266
|
-
}
|
|
1267
|
-
else if (calleeName === 'prop') {
|
|
1268
|
-
this.processStorageProp(cs, cid);
|
|
1269
|
-
}
|
|
1270
|
-
else if (calleeName === 'set') {
|
|
1271
|
-
this.processStorageSet(cs, cid);
|
|
1272
|
-
}
|
|
1273
|
-
else if (calleeName === 'get') {
|
|
1274
|
-
this.processStorageGet(cs, cid);
|
|
1275
|
-
}
|
|
1276
|
-
return true;
|
|
1277
|
-
}
|
|
1278
|
-
else if (storageType === Pag_1.StorageType.LOCAL_STORAGE) {
|
|
1279
|
-
// TODO: LocalStorage is not Static
|
|
1280
|
-
}
|
|
1281
|
-
return false;
|
|
1282
|
-
}
|
|
1283
|
-
processStorageSetOrCreate(cs, cid) {
|
|
1284
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1285
|
-
if (!propertyStr) {
|
|
1286
|
-
return;
|
|
1287
|
-
}
|
|
1288
|
-
let propertyName = propertyStr;
|
|
1289
|
-
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1290
|
-
let storageObj = cs.args[1];
|
|
1291
|
-
this.addPropertyLinkEdge(propertyNode, storageObj, cid, cs.callStmt, Pag_1.StorageLinkEdgeType.Local2Property);
|
|
1292
|
-
}
|
|
1293
|
-
processStorageLink(cs, cid) {
|
|
1294
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1295
|
-
if (!propertyStr) {
|
|
1296
|
-
return;
|
|
1297
|
-
}
|
|
1298
|
-
let propertyName = propertyStr;
|
|
1299
|
-
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1300
|
-
let leftOp = cs.callStmt.getLeftOp();
|
|
1301
|
-
let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
|
|
1302
|
-
if (linkedOpNode instanceof Pag_1.PagLocalNode) {
|
|
1303
|
-
linkedOpNode.setStorageLink(Pag_1.StorageType.APP_STORAGE, propertyName);
|
|
1304
|
-
}
|
|
1305
|
-
this.pag.addPagEdge(propertyNode, linkedOpNode, Pag_1.PagEdgeKind.Copy);
|
|
1306
|
-
this.pag.addPagEdge(linkedOpNode, propertyNode, Pag_1.PagEdgeKind.Copy);
|
|
1307
|
-
}
|
|
1308
|
-
processStorageProp(cs, cid) {
|
|
1309
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1310
|
-
if (!propertyStr) {
|
|
1311
|
-
return;
|
|
1312
|
-
}
|
|
1313
|
-
let propertyName = propertyStr;
|
|
1314
|
-
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1315
|
-
let leftOp = cs.callStmt.getLeftOp();
|
|
1316
|
-
let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
|
|
1317
|
-
if (linkedOpNode instanceof Pag_1.PagLocalNode) {
|
|
1318
|
-
linkedOpNode.setStorageLink(Pag_1.StorageType.APP_STORAGE, propertyName);
|
|
1319
|
-
}
|
|
1320
|
-
this.pag.addPagEdge(propertyNode, linkedOpNode, Pag_1.PagEdgeKind.Copy);
|
|
1321
|
-
}
|
|
1322
|
-
processStorageSet(cs, cid) {
|
|
1323
|
-
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
1324
|
-
if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
1325
|
-
let base = ivkExpr.getBase();
|
|
1326
|
-
let baseNode = this.pag.getOrNewNode(cid, base);
|
|
1327
|
-
if (baseNode.isStorageLinked()) {
|
|
1328
|
-
let argsNode = this.pag.getOrNewNode(cid, cs.args[0]);
|
|
1329
|
-
this.pag.addPagEdge(argsNode, baseNode, Pag_1.PagEdgeKind.Copy);
|
|
1330
|
-
}
|
|
1331
|
-
}
|
|
1332
|
-
else if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
1333
|
-
// TODO: process AppStorage.set()
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
processStorageGet(cs, cid) {
|
|
1337
|
-
if (!(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
|
|
1338
|
-
return;
|
|
1339
|
-
}
|
|
1340
|
-
let leftOp = cs.callStmt.getLeftOp();
|
|
1341
|
-
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
1342
|
-
let propertyName;
|
|
1343
|
-
if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
1344
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1345
|
-
if (propertyStr) {
|
|
1346
|
-
propertyName = propertyStr;
|
|
1347
|
-
}
|
|
1348
|
-
}
|
|
1349
|
-
else if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
1350
|
-
let baseNode = this.pag.getOrNewNode(cid, ivkExpr.getBase());
|
|
1351
|
-
if (baseNode.isStorageLinked()) {
|
|
1352
|
-
propertyName = baseNode.getStorage().PropertyName;
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
let propertyNode = this.getPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1356
|
-
if (!propertyNode) {
|
|
1357
|
-
return;
|
|
1358
|
-
}
|
|
1359
|
-
this.pag.addPagEdge(propertyNode, this.pag.getOrNewNode(cid, leftOp, cs.callStmt), Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
1360
|
-
}
|
|
1361
|
-
getPropertyName(value) {
|
|
1362
|
-
if (value instanceof Local_1.Local) {
|
|
1363
|
-
let type = value.getType();
|
|
1364
|
-
if (type instanceof Type_1.StringType) {
|
|
1365
|
-
return type.getName();
|
|
1366
|
-
}
|
|
1367
|
-
}
|
|
1368
|
-
else if (value instanceof Constant_1.Constant) {
|
|
1369
|
-
return value.getValue();
|
|
1370
|
-
}
|
|
1371
|
-
return undefined;
|
|
1372
|
-
}
|
|
1373
|
-
/**
|
|
1374
|
-
* get storageType enum with method's Declaring ClassName
|
|
1375
|
-
*
|
|
1376
|
-
* @param storageName ClassName that method belongs to, currently support AppStorage and SubscribedAbstractProperty
|
|
1377
|
-
* SubscribedAbstractProperty: in following listing, `link1` is infered as ClassType `SubscribedAbstractProperty`,
|
|
1378
|
-
* it needs to get PAG node to check the StorageType
|
|
1379
|
-
* let link1: SubscribedAbstractProperty<A> = AppStorage.link('PropA');
|
|
1380
|
-
* link1.set(a);
|
|
1381
|
-
* @param cs: for search PAG node in SubscribedAbstractProperty
|
|
1382
|
-
* @param cid: for search PAG node in SubscribedAbstractProperty
|
|
1383
|
-
* @returns StorageType enum
|
|
1384
|
-
*/
|
|
1385
|
-
getStorageType(storageName, cs, cid) {
|
|
1386
|
-
switch (storageName) {
|
|
1387
|
-
case 'AppStorage':
|
|
1388
|
-
return Pag_1.StorageType.APP_STORAGE;
|
|
1389
|
-
case 'SubscribedAbstractProperty': {
|
|
1390
|
-
let calleeBaseLocal = cs.callStmt.getInvokeExpr().getBase();
|
|
1391
|
-
let calleeBaseLocalNode = this.pag.getOrNewNode(cid, calleeBaseLocal);
|
|
1392
|
-
if (calleeBaseLocalNode.isStorageLinked()) {
|
|
1393
|
-
let storage = calleeBaseLocalNode.getStorage();
|
|
1394
|
-
return storage.StorageType;
|
|
1395
|
-
}
|
|
1396
|
-
return Pag_1.StorageType.Undefined;
|
|
1397
|
-
}
|
|
1398
|
-
default:
|
|
1399
|
-
return Pag_1.StorageType.Undefined;
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
994
|
/**\
|
|
1403
995
|
* ArkNewExpr, ArkNewArrayExpr, function ptr, globalThis
|
|
1404
996
|
*/
|
|
@@ -1650,25 +1242,6 @@ class PagBuilder {
|
|
|
1650
1242
|
resetUpdatedNodes() {
|
|
1651
1243
|
this.updatedNodesThisRound.clear();
|
|
1652
1244
|
}
|
|
1653
|
-
transferArrayValues(method, arrayLocal) {
|
|
1654
|
-
if (!(arrayLocal instanceof Local_1.Local) || !(arrayLocal.getType() instanceof Type_1.ArrayType)) {
|
|
1655
|
-
return [];
|
|
1656
|
-
}
|
|
1657
|
-
/**
|
|
1658
|
-
* TODO: get array element values
|
|
1659
|
-
* need to resolve multi dimension array
|
|
1660
|
-
*/
|
|
1661
|
-
const usedValuesInArray = arrayLocal.getUsedStmts().flatMap(stmt => {
|
|
1662
|
-
if (stmt instanceof Stmt_1.ArkAssignStmt) {
|
|
1663
|
-
const rightOp = stmt.getRightOp();
|
|
1664
|
-
if (rightOp instanceof Local_1.Local) {
|
|
1665
|
-
return rightOp;
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
return [];
|
|
1669
|
-
});
|
|
1670
|
-
return usedValuesInArray;
|
|
1671
|
-
}
|
|
1672
1245
|
getContextSelector() {
|
|
1673
1246
|
return this.ctxSelector;
|
|
1674
1247
|
}
|