arkanalyzer 1.0.42 → 1.0.44
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/lib/Scene.d.ts +1 -2
- package/lib/Scene.d.ts.map +1 -1
- package/lib/Scene.js +59 -47
- 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 +62 -495
- 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/common/DummyMainCreater.js +1 -1
- package/lib/core/common/IRInference.d.ts.map +1 -1
- package/lib/core/common/IRInference.js +4 -0
- package/lib/core/common/SdkUtils.d.ts +1 -1
- package/lib/core/common/SdkUtils.d.ts.map +1 -1
- package/lib/core/common/SdkUtils.js +18 -18
- package/lib/core/common/TypeInference.d.ts.map +1 -1
- package/lib/core/common/TypeInference.js +11 -2
- package/lib/core/graph/builder/CfgBuilder.js +1 -1
- package/lib/core/graph/builder/ConditionBuilder.js +1 -1
- package/lib/core/model/ArkClass.d.ts.map +1 -1
- package/lib/core/model/ArkClass.js +2 -1
- package/lib/core/model/builder/ArkMethodBuilder.d.ts +1 -0
- package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkMethodBuilder.js +40 -5
- package/lib/core/model/builder/BodyBuilder.js +1 -1
- package/lib/pass/Dispatcher.d.ts +2 -2
- package/lib/pass/Dispatcher.d.ts.map +1 -1
- package/lib/pass/Pass.d.ts +3 -3
- package/lib/pass/Pass.d.ts.map +1 -1
- package/lib/pass/ScenePassMgr.d.ts +4 -4
- package/lib/pass/ScenePassMgr.d.ts.map +1 -1
- 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/{SceneValidator.d.ts → validators/Validator.d.ts} +100 -108
- package/lib/pass/validators/Validator.d.ts.map +1 -0
- package/lib/pass/{SceneValidator.js → validators/Validator.js} +147 -143
- 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/source/SourceStmt.js +1 -1
- package/lib/save/source/SourceTransformer.d.ts.map +1 -1
- package/lib/save/source/SourceTransformer.js +16 -1
- package/lib/utils/FileUtils.js +1 -1
- package/package.json +2 -2
- package/lib/pass/SceneValidator.d.ts.map +0 -1
|
@@ -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);
|
|
@@ -342,9 +320,12 @@ class PagBuilder {
|
|
|
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
|
|
@@ -462,18 +443,18 @@ class PagBuilder {
|
|
|
462
443
|
return srcNodes;
|
|
463
444
|
}
|
|
464
445
|
let staticCS = this.cg.getCallSiteManager().cloneCallSiteFromDyn(cs, dstCGNode.getID());
|
|
465
|
-
let calleeCid = this.ctxSelector.selectContext(cid, staticCS, baseClassPTNode, dstCGNode.getID());
|
|
466
446
|
if (this.scale === PointerAnalysisConfig_1.PtaAnalysisScale.MethodLevel) {
|
|
467
|
-
srcNodes.push(...this.addStaticPagCallReturnEdge(staticCS,
|
|
447
|
+
srcNodes.push(...this.addStaticPagCallReturnEdge(staticCS, cid, baseClassPTNode));
|
|
468
448
|
continue;
|
|
469
449
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
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;
|
|
476
456
|
}
|
|
457
|
+
srcNodes.push(...this.processNormalMethodPagCallEdge(staticCS, cid, baseClassPTNode));
|
|
477
458
|
}
|
|
478
459
|
return srcNodes;
|
|
479
460
|
}
|
|
@@ -482,6 +463,7 @@ class PagBuilder {
|
|
|
482
463
|
* handle both PtrInvokeExpr and InstanceInvokeExpr
|
|
483
464
|
*/
|
|
484
465
|
getDynamicCallee(ptNode, value, ivkExpr, cs) {
|
|
466
|
+
var _a, _b;
|
|
485
467
|
let callee = [];
|
|
486
468
|
if (ptNode instanceof Pag_1.PagFuncNode) {
|
|
487
469
|
// function ptr invoke
|
|
@@ -498,20 +480,22 @@ class PagBuilder {
|
|
|
498
480
|
if (!(value instanceof Expr_1.ArkNewExpr || value instanceof Expr_1.ArkNewArrayExpr)) {
|
|
499
481
|
return callee;
|
|
500
482
|
}
|
|
501
|
-
let tempCallee;
|
|
502
483
|
// try to get callee by MethodSignature
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
let cls;
|
|
507
|
-
cls = this.scene.getClass(clsSig);
|
|
508
|
-
while (!tempCallee && cls) {
|
|
509
|
-
tempCallee = cls.getMethodWithName(calleeName);
|
|
510
|
-
cls = cls.getSuperClass();
|
|
511
|
-
}
|
|
512
|
-
if (!tempCallee) {
|
|
513
|
-
tempCallee = this.scene.getMethod(ivkExpr.getMethodSignature());
|
|
484
|
+
const getClassSignature = (value) => {
|
|
485
|
+
if (value instanceof Expr_1.ArkNewExpr) {
|
|
486
|
+
return value.getType().getClassSignature();
|
|
514
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;
|
|
515
499
|
}
|
|
516
500
|
if (!tempCallee && cs.args) {
|
|
517
501
|
// while pts has {o_1, o_2} and invoke expr represents a method that only {o_1} has
|
|
@@ -530,11 +514,12 @@ class PagBuilder {
|
|
|
530
514
|
}
|
|
531
515
|
return callee;
|
|
532
516
|
}
|
|
533
|
-
processNormalMethodPagCallEdge(staticCS, cid,
|
|
517
|
+
processNormalMethodPagCallEdge(staticCS, cid, baseClassPTNode) {
|
|
534
518
|
let srcNodes = [];
|
|
535
519
|
let ivkExpr = staticCS.callStmt.getInvokeExpr();
|
|
536
520
|
let ptNode = this.pag.getNode(baseClassPTNode);
|
|
537
521
|
let dstCGNode = this.cg.getNode(staticCS.calleeFuncID);
|
|
522
|
+
let calleeCid = this.ctxSelector.selectContext(cid, staticCS, baseClassPTNode, dstCGNode.getID());
|
|
538
523
|
let callee = this.cg.getArkMethodByFuncID(staticCS.calleeFuncID);
|
|
539
524
|
// Dynamic call, Ptr call, normal SDK call
|
|
540
525
|
srcNodes.push(...this.addStaticPagCallEdge(staticCS, cid, calleeCid, ptNode));
|
|
@@ -558,126 +543,6 @@ class PagBuilder {
|
|
|
558
543
|
}
|
|
559
544
|
return srcNodes;
|
|
560
545
|
}
|
|
561
|
-
/**
|
|
562
|
-
* include container API, Function API
|
|
563
|
-
*/
|
|
564
|
-
processBuiltInMethodPagCallEdge(staticCS, cid, calleeCid, baseClassPTNode) {
|
|
565
|
-
let srcNodes = [];
|
|
566
|
-
let ivkExpr = staticCS.callStmt.getInvokeExpr();
|
|
567
|
-
let callee = this.scene.getMethod(ivkExpr.getMethodSignature());
|
|
568
|
-
let realCallee = this.cg.getArkMethodByFuncID(staticCS.calleeFuncID);
|
|
569
|
-
if (!callee) {
|
|
570
|
-
return srcNodes;
|
|
571
|
-
}
|
|
572
|
-
let builtInType = (0, PTAUtils_1.getBuiltInApiType)(callee.getSignature());
|
|
573
|
-
if (builtInType === PTAUtils_1.BuiltApiType.NotBuiltIn || !realCallee) {
|
|
574
|
-
return srcNodes;
|
|
575
|
-
}
|
|
576
|
-
switch (builtInType) {
|
|
577
|
-
case PTAUtils_1.BuiltApiType.SetAdd:
|
|
578
|
-
case PTAUtils_1.BuiltApiType.MapSet:
|
|
579
|
-
this.processContainerPagCallEdge(staticCS, cid, baseClassPTNode, builtInType);
|
|
580
|
-
break;
|
|
581
|
-
case PTAUtils_1.BuiltApiType.FunctionCall:
|
|
582
|
-
/**
|
|
583
|
-
* set this and param
|
|
584
|
-
* function.call(thisArg, arg1, arg2, ...)
|
|
585
|
-
*/
|
|
586
|
-
this.handleFunctionCall(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode);
|
|
587
|
-
break;
|
|
588
|
-
case PTAUtils_1.BuiltApiType.FunctionApply:
|
|
589
|
-
/**
|
|
590
|
-
* set this, resolve array param
|
|
591
|
-
* function.apply(thisArg, [argsArray])
|
|
592
|
-
*/
|
|
593
|
-
this.handleFunctionApply(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode);
|
|
594
|
-
break;
|
|
595
|
-
case PTAUtils_1.BuiltApiType.FunctionBind:
|
|
596
|
-
/**
|
|
597
|
-
* clone the function node and add the this pointer, origin callSite, args offset to it
|
|
598
|
-
* let f = function.bind(thisArg, arg1, arg2, ...)
|
|
599
|
-
* f();
|
|
600
|
-
*/
|
|
601
|
-
this.handleFunctionBind(staticCS, cid, baseClassPTNode, srcNodes);
|
|
602
|
-
break;
|
|
603
|
-
default:
|
|
604
|
-
}
|
|
605
|
-
return srcNodes;
|
|
606
|
-
}
|
|
607
|
-
processContainerPagCallEdge(cs, cid, baseClassPTNode, type) {
|
|
608
|
-
let srcNodes = [];
|
|
609
|
-
let calleeNode = this.cg.getNode(cs.calleeFuncID);
|
|
610
|
-
let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
|
|
611
|
-
let ptNode = this.pag.getNode(baseClassPTNode);
|
|
612
|
-
if (!calleeMethod || !(ptNode instanceof Pag_1.PagNewContainerExprNode)) {
|
|
613
|
-
return srcNodes;
|
|
614
|
-
}
|
|
615
|
-
let containerValue = cs.callStmt.getInvokeExpr().getBase();
|
|
616
|
-
const containerValueProcess = (argIndex) => {
|
|
617
|
-
let srcNode = this.pag.getOrNewNode(cid, cs.args[argIndex], cs.callStmt);
|
|
618
|
-
let realContainerFieldPagNode = this.pag.getOrClonePagContainerFieldNode(baseClassPTNode, undefined, containerValue);
|
|
619
|
-
if (realContainerFieldPagNode) {
|
|
620
|
-
// In some cases, the value of a variable of array type may not be an explicit array object,
|
|
621
|
-
// and the value of `realContainerFieldPagNode` will be undefined.
|
|
622
|
-
this.pag.addPagEdge(srcNode, realContainerFieldPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
623
|
-
srcNodes.push(srcNode.getID());
|
|
624
|
-
}
|
|
625
|
-
};
|
|
626
|
-
if (type === PTAUtils_1.BuiltApiType.SetAdd) {
|
|
627
|
-
containerValueProcess(0);
|
|
628
|
-
}
|
|
629
|
-
else if (type === PTAUtils_1.BuiltApiType.MapSet) {
|
|
630
|
-
containerValueProcess(1);
|
|
631
|
-
}
|
|
632
|
-
return srcNodes;
|
|
633
|
-
}
|
|
634
|
-
handleFunctionCall(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode) {
|
|
635
|
-
this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID));
|
|
636
|
-
srcNodes.push(...this.addCallParamPagEdge(realCallee, staticCS.args, staticCS.callStmt, cid, calleeCid, 1));
|
|
637
|
-
this.addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid);
|
|
638
|
-
}
|
|
639
|
-
handleFunctionApply(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode) {
|
|
640
|
-
this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID));
|
|
641
|
-
let callerMethod = this.cg.getArkMethodByFuncID(staticCS.callerFuncID);
|
|
642
|
-
if (!callerMethod) {
|
|
643
|
-
throw new Error('Cannot get caller method');
|
|
644
|
-
}
|
|
645
|
-
let argsRealValues = this.transferArrayValues(callerMethod, staticCS.args[1]);
|
|
646
|
-
srcNodes.push(...this.addCallParamPagEdge(realCallee, argsRealValues, staticCS.callStmt, cid, calleeCid, 0));
|
|
647
|
-
this.addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid);
|
|
648
|
-
}
|
|
649
|
-
handleFunctionBind(staticCS, cid, baseClassPTNode, srcNodes) {
|
|
650
|
-
let srcNode = this.pag.getOrClonePagFuncNode(baseClassPTNode);
|
|
651
|
-
if (!srcNode) {
|
|
652
|
-
return;
|
|
653
|
-
}
|
|
654
|
-
this.setFunctionThisPt(staticCS, srcNode, cid);
|
|
655
|
-
let dstNode = this.getOrNewPagNode(cid, staticCS.callStmt.getLeftOp());
|
|
656
|
-
this.pag.addPagEdge(srcNode, dstNode, Pag_1.PagEdgeKind.Copy, staticCS.callStmt);
|
|
657
|
-
srcNodes.push(srcNode.getID());
|
|
658
|
-
srcNode.setCS(staticCS);
|
|
659
|
-
srcNode.setArgsOffset(1);
|
|
660
|
-
srcNode.setOriginCid(cid);
|
|
661
|
-
}
|
|
662
|
-
addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid) {
|
|
663
|
-
if (!(staticCS.args[0] instanceof Constant_1.NullConstant) && !realCallee.isStatic()) {
|
|
664
|
-
let srcNodeID = this.addThisRefCallEdge(cid, staticCS.args[0], realCallee, calleeCid, staticCS.callerFuncID);
|
|
665
|
-
if (srcNodeID !== -1) {
|
|
666
|
-
srcNodes.push(srcNodeID);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
setFunctionThisPt(staticCS, srcNode, cid) {
|
|
671
|
-
let thisLocal = staticCS.args[0];
|
|
672
|
-
if (!(thisLocal instanceof Local_1.Local)) {
|
|
673
|
-
return;
|
|
674
|
-
}
|
|
675
|
-
let thisInstanceLocal = this.getRealThisLocal(thisLocal, staticCS.callerFuncID);
|
|
676
|
-
let baseThisNode = this.pag.getOrNewNode(cid, thisInstanceLocal);
|
|
677
|
-
for (let pt of baseThisNode.getPointTo()) {
|
|
678
|
-
srcNode.setThisPt(pt);
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
546
|
handleUnkownDynamicCall(cs, cid) {
|
|
682
547
|
var _a;
|
|
683
548
|
let srcNodes = [];
|
|
@@ -709,13 +574,6 @@ class PagBuilder {
|
|
|
709
574
|
if (!callerNode) {
|
|
710
575
|
throw new Error('Can not get caller method node');
|
|
711
576
|
}
|
|
712
|
-
if (this.processStorage(cs, dstCGNode, cid)) {
|
|
713
|
-
if (ivkExpr.getArgs().length !== 0) {
|
|
714
|
-
// for AppStorage.set() instance invoke, add obj to reanalyze list
|
|
715
|
-
let argsNode = this.pag.getOrNewNode(cid, cs.args[0]);
|
|
716
|
-
srcNodes.push(argsNode.getID());
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
577
|
logger.warn(`\tAdd call edge of unknown call ${callee.getSignature().toString()}`);
|
|
720
578
|
this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt);
|
|
721
579
|
if (!this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
|
|
@@ -815,7 +673,7 @@ class PagBuilder {
|
|
|
815
673
|
return srcNodes;
|
|
816
674
|
}
|
|
817
675
|
if (calleeNode.isSdkMethod()) {
|
|
818
|
-
|
|
676
|
+
logger.error(`SDK method ${calleeMethod.getSignature().toString()} shoule be handled by plugin`);
|
|
819
677
|
return srcNodes;
|
|
820
678
|
}
|
|
821
679
|
if (!calleeMethod.getCfg()) {
|
|
@@ -833,16 +691,17 @@ class PagBuilder {
|
|
|
833
691
|
argsOffset = (_c = ptNode.getArgsOffset()) !== null && _c !== void 0 ? _c : 0;
|
|
834
692
|
callerCid = (_d = ptNode.getOriginCid()) !== null && _d !== void 0 ? _d : callerCid;
|
|
835
693
|
}
|
|
836
|
-
srcNodes.push(...this.addCallParamPagEdge(calleeMethod, realArgs, cs
|
|
694
|
+
srcNodes.push(...this.addCallParamPagEdge(calleeMethod, realArgs, cs, callerCid, calleeCid, argsOffset));
|
|
837
695
|
srcNodes.push(...this.addCallReturnPagEdge(calleeMethod, cs.callStmt, callerCid, calleeCid));
|
|
838
696
|
return srcNodes;
|
|
839
697
|
}
|
|
840
698
|
/**
|
|
841
699
|
* only process the param PAG edge for invoke stmt
|
|
842
700
|
*/
|
|
843
|
-
addCallParamPagEdge(calleeMethod, args,
|
|
844
|
-
var _a;
|
|
845
|
-
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
|
|
846
705
|
.getCfg()
|
|
847
706
|
.getStmts()
|
|
848
707
|
.filter(stmt => stmt instanceof Stmt_1.ArkAssignStmt && stmt.getRightOp() instanceof Ref_1.ArkParameterRef)
|
|
@@ -854,7 +713,7 @@ class PagBuilder {
|
|
|
854
713
|
* cs.args is anonymous method local, will have only 1 parameter
|
|
855
714
|
* but inside foreach will have >= 1 parameters
|
|
856
715
|
*/
|
|
857
|
-
if (((
|
|
716
|
+
if (((_b = callStmt.getInvokeExpr()) === null || _b === void 0 ? void 0 : _b.getMethodSignature().getMethodSubSignature().getMethodName()) === 'forEach') {
|
|
858
717
|
srcNodes.push(...this.addForeachParamPagEdge(callerCid, calleeCid, callStmt, params));
|
|
859
718
|
return srcNodes;
|
|
860
719
|
}
|
|
@@ -937,38 +796,20 @@ class PagBuilder {
|
|
|
937
796
|
}
|
|
938
797
|
return srcNodes;
|
|
939
798
|
}
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
799
|
+
/**
|
|
800
|
+
* for method level call graph, add return edge
|
|
801
|
+
*/
|
|
802
|
+
addStaticPagCallReturnEdge(cs, cid, baseClassPTNode) {
|
|
944
803
|
let srcNodes = [];
|
|
945
804
|
// Add reachable
|
|
946
805
|
let calleeNode = this.cg.getNode(cs.calleeFuncID);
|
|
947
806
|
let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
|
|
807
|
+
let calleeCid = this.ctxSelector.selectContext(cid, cs, baseClassPTNode, cs.calleeFuncID);
|
|
948
808
|
if (!calleeMethod) {
|
|
949
809
|
// TODO: check if nodes need to delete
|
|
950
810
|
return srcNodes;
|
|
951
811
|
}
|
|
952
|
-
srcNodes.push(...this.addSDKMethodReturnPagEdge(cs,
|
|
953
|
-
return srcNodes;
|
|
954
|
-
}
|
|
955
|
-
addSDKMethodPagCallEdge(cs, callerCid, calleeCid) {
|
|
956
|
-
let srcNodes = [];
|
|
957
|
-
let calleeNode = this.cg.getNode(cs.calleeFuncID);
|
|
958
|
-
let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
|
|
959
|
-
if (!calleeMethod) {
|
|
960
|
-
return srcNodes;
|
|
961
|
-
}
|
|
962
|
-
let methodType = (0, PTAUtils_1.getBuiltInApiType)(calleeMethod.getSignature());
|
|
963
|
-
// block the container SDK
|
|
964
|
-
if (methodType === PTAUtils_1.BuiltApiType.SetAdd || PTAUtils_1.BuiltApiType.MapSet) {
|
|
965
|
-
return srcNodes;
|
|
966
|
-
}
|
|
967
|
-
if (!this.methodParamValueMap.has(calleeNode.getID())) {
|
|
968
|
-
this.buildSDKFuncPag(calleeNode.getID());
|
|
969
|
-
}
|
|
970
|
-
srcNodes.push(...this.addSDKMethodReturnPagEdge(cs, callerCid, calleeCid, calleeMethod));
|
|
971
|
-
srcNodes.push(...this.addSDKMethodParamPagEdge(cs, callerCid, calleeCid, calleeNode.getID()));
|
|
812
|
+
srcNodes.push(...this.addSDKMethodReturnPagEdge(cs, cid, calleeCid, calleeMethod)); // TODO: ???? why sdk
|
|
972
813
|
return srcNodes;
|
|
973
814
|
}
|
|
974
815
|
addSDKMethodReturnPagEdge(cs, callerCid, calleeCid, calleeMethod) {
|
|
@@ -996,52 +837,6 @@ class PagBuilder {
|
|
|
996
837
|
srcNodes.push(srcPagNode.getID());
|
|
997
838
|
return srcNodes;
|
|
998
839
|
}
|
|
999
|
-
addSDKMethodParamPagEdge(cs, callerCid, calleeCid, funcID) {
|
|
1000
|
-
var _a, _b;
|
|
1001
|
-
let argNum = (_a = cs.args) === null || _a === void 0 ? void 0 : _a.length;
|
|
1002
|
-
let srcNodes = [];
|
|
1003
|
-
if (!argNum) {
|
|
1004
|
-
return srcNodes;
|
|
1005
|
-
}
|
|
1006
|
-
// add args to parameters edges
|
|
1007
|
-
for (let i = 0; i < argNum; i++) {
|
|
1008
|
-
let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b[i];
|
|
1009
|
-
let paramValue;
|
|
1010
|
-
if (arg instanceof Local_1.Local && arg.getType() instanceof Type_1.FunctionType) {
|
|
1011
|
-
// TODO: cannot find value
|
|
1012
|
-
paramValue = this.methodParamValueMap.get(funcID).get(i);
|
|
1013
|
-
}
|
|
1014
|
-
else {
|
|
1015
|
-
continue;
|
|
1016
|
-
}
|
|
1017
|
-
if (!(arg && paramValue)) {
|
|
1018
|
-
continue;
|
|
1019
|
-
}
|
|
1020
|
-
// Get or create new PAG node for argument and parameter
|
|
1021
|
-
let srcPagNode = this.getOrNewPagNode(callerCid, arg, cs.callStmt);
|
|
1022
|
-
let dstPagNode = this.getOrNewPagNode(calleeCid, paramValue, cs.callStmt);
|
|
1023
|
-
if (dstPagNode instanceof Pag_1.PagLocalNode) {
|
|
1024
|
-
// set the fake param Value in PagLocalNode
|
|
1025
|
-
/**
|
|
1026
|
-
* TODO: !!!
|
|
1027
|
-
* some API param is in the form of anonymous method:
|
|
1028
|
-
* component/common.d.ts
|
|
1029
|
-
* declare function animateTo(value: AnimateParam, event: () => void): void;
|
|
1030
|
-
*
|
|
1031
|
-
* this param fake Value will create PagFuncNode rather than PagLocalNode
|
|
1032
|
-
* when this API is called, the anonymous method pointer will not be able to pass into the fake Value PagNode
|
|
1033
|
-
*/
|
|
1034
|
-
dstPagNode.setSdkParam();
|
|
1035
|
-
let sdkParamInvokeStmt = new Stmt_1.ArkInvokeStmt(new Expr_1.ArkPtrInvokeExpr(arg.getType().getMethodSignature(), paramValue, []));
|
|
1036
|
-
// create new DynCallSite
|
|
1037
|
-
let sdkParamCallSite = this.cg.getCallSiteManager().newDynCallSite(sdkParamInvokeStmt, undefined, undefined, funcID);
|
|
1038
|
-
dstPagNode.addRelatedDynCallSite(sdkParamCallSite);
|
|
1039
|
-
}
|
|
1040
|
-
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
1041
|
-
srcNodes.push(srcPagNode.getID());
|
|
1042
|
-
}
|
|
1043
|
-
return srcNodes;
|
|
1044
|
-
}
|
|
1045
840
|
getOrNewPagNode(cid, v, s) {
|
|
1046
841
|
// globalThis process can not be removed while all `globalThis` ref is the same Value
|
|
1047
842
|
if (v instanceof Local_1.Local && v.getName() === TSConst_1.GLOBAL_THIS_NAME && v.getDeclaringStmt() == null) {
|
|
@@ -1056,63 +851,6 @@ class PagBuilder {
|
|
|
1056
851
|
getOrNewGlobalThisNode(cid) {
|
|
1057
852
|
return this.pag.getOrNewNode(cid, this.getGlobalThisValue());
|
|
1058
853
|
}
|
|
1059
|
-
/**
|
|
1060
|
-
* search the storage map to get propertyNode with given storage and propertyFieldName
|
|
1061
|
-
* @param storage storage type: AppStorage, LocalStorage etc.
|
|
1062
|
-
* @param propertyName string property key
|
|
1063
|
-
* @returns propertyNode: PagLocalNode
|
|
1064
|
-
*/
|
|
1065
|
-
getOrNewPropertyNode(storage, propertyName, stmt) {
|
|
1066
|
-
let propertyNode = this.getPropertyNode(storage, propertyName, stmt);
|
|
1067
|
-
if (propertyNode) {
|
|
1068
|
-
return propertyNode;
|
|
1069
|
-
}
|
|
1070
|
-
let storageMap = this.storagePropertyMap.get(storage);
|
|
1071
|
-
let propertyLocal = new Local_1.Local(propertyName);
|
|
1072
|
-
storageMap.set(propertyName, propertyLocal);
|
|
1073
|
-
this.storagePropertyMap.set(storage, storageMap);
|
|
1074
|
-
return this.getOrNewPagNode(-1, propertyLocal, stmt);
|
|
1075
|
-
}
|
|
1076
|
-
getPropertyNode(storage, propertyName, stmt) {
|
|
1077
|
-
let storageMap = this.storagePropertyMap.get(storage);
|
|
1078
|
-
let propertyLocal;
|
|
1079
|
-
if (!storageMap) {
|
|
1080
|
-
storageMap = new Map();
|
|
1081
|
-
this.storagePropertyMap.set(storage, storageMap);
|
|
1082
|
-
}
|
|
1083
|
-
if (storageMap.has(propertyName)) {
|
|
1084
|
-
propertyLocal = storageMap.get(propertyName);
|
|
1085
|
-
}
|
|
1086
|
-
if (propertyLocal) {
|
|
1087
|
-
return this.getOrNewPagNode(-1, propertyLocal, stmt);
|
|
1088
|
-
}
|
|
1089
|
-
return undefined;
|
|
1090
|
-
}
|
|
1091
|
-
/**
|
|
1092
|
-
* add PagEdge
|
|
1093
|
-
* @param edgeKind: edge kind differs from API
|
|
1094
|
-
* @param propertyNode: PAG node created by protpertyName
|
|
1095
|
-
* @param obj: heapObj stored with Storage API
|
|
1096
|
-
*/
|
|
1097
|
-
addPropertyLinkEdge(propertyNode, storageObj, cid, stmt, edgeKind) {
|
|
1098
|
-
if (!(storageObj.getType() instanceof Type_1.ClassType)) {
|
|
1099
|
-
return false;
|
|
1100
|
-
}
|
|
1101
|
-
if (edgeKind === Pag_1.StorageLinkEdgeType.Property2Local) {
|
|
1102
|
-
// propertyNode --> objNode
|
|
1103
|
-
this.pag.addPagEdge(propertyNode, this.pag.getOrNewNode(cid, storageObj), Pag_1.PagEdgeKind.Copy, stmt);
|
|
1104
|
-
}
|
|
1105
|
-
else if (edgeKind === Pag_1.StorageLinkEdgeType.Local2Property) {
|
|
1106
|
-
// propertyNode <-- objNode
|
|
1107
|
-
this.pag.addPagEdge(this.pag.getOrNewNode(cid, storageObj), propertyNode, Pag_1.PagEdgeKind.Copy, stmt);
|
|
1108
|
-
}
|
|
1109
|
-
else if (edgeKind === Pag_1.StorageLinkEdgeType.TwoWay) {
|
|
1110
|
-
// propertyNode <-> objNode
|
|
1111
|
-
this.pag.addPagEdge(propertyNode, this.pag.getOrNewNode(cid, storageObj), Pag_1.PagEdgeKind.Copy, stmt);
|
|
1112
|
-
this.pag.addPagEdge(this.pag.getOrNewNode(cid, storageObj), propertyNode, Pag_1.PagEdgeKind.Copy, stmt);
|
|
1113
|
-
}
|
|
1114
|
-
return true;
|
|
1115
|
-
}
|
|
1116
854
|
/*
|
|
1117
855
|
* In ArkIR, ArkField has multiple instances for each stmt which use it
|
|
1118
856
|
* But the unique one is needed for pointer analysis
|
|
@@ -1253,158 +991,6 @@ class PagBuilder {
|
|
|
1253
991
|
}
|
|
1254
992
|
return Pag_1.PagEdgeKind.Unknown;
|
|
1255
993
|
}
|
|
1256
|
-
/**
|
|
1257
|
-
* process Storage API
|
|
1258
|
-
* @returns boolean: check if the cs represent a Storage API, no matter the API will success or fail
|
|
1259
|
-
*/
|
|
1260
|
-
processStorage(cs, calleeCGNode, cid) {
|
|
1261
|
-
let storageName = calleeCGNode.getMethod().getDeclaringClassSignature().getClassName();
|
|
1262
|
-
let storageType = this.getStorageType(storageName, cs, cid);
|
|
1263
|
-
// TODO: add other storages
|
|
1264
|
-
if (storageType === Pag_1.StorageType.APP_STORAGE) {
|
|
1265
|
-
let calleeName = calleeCGNode.getMethod().getMethodSubSignature().getMethodName();
|
|
1266
|
-
// TODO: complete AppStorage API
|
|
1267
|
-
if (calleeName === 'setOrCreate') {
|
|
1268
|
-
this.processStorageSetOrCreate(cs, cid);
|
|
1269
|
-
}
|
|
1270
|
-
else if (calleeName === 'link') {
|
|
1271
|
-
this.processStorageLink(cs, cid);
|
|
1272
|
-
}
|
|
1273
|
-
else if (calleeName === 'prop') {
|
|
1274
|
-
this.processStorageProp(cs, cid);
|
|
1275
|
-
}
|
|
1276
|
-
else if (calleeName === 'set') {
|
|
1277
|
-
this.processStorageSet(cs, cid);
|
|
1278
|
-
}
|
|
1279
|
-
else if (calleeName === 'get') {
|
|
1280
|
-
this.processStorageGet(cs, cid);
|
|
1281
|
-
}
|
|
1282
|
-
return true;
|
|
1283
|
-
}
|
|
1284
|
-
else if (storageType === Pag_1.StorageType.LOCAL_STORAGE) {
|
|
1285
|
-
// TODO: LocalStorage is not Static
|
|
1286
|
-
}
|
|
1287
|
-
return false;
|
|
1288
|
-
}
|
|
1289
|
-
processStorageSetOrCreate(cs, cid) {
|
|
1290
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1291
|
-
if (!propertyStr) {
|
|
1292
|
-
return;
|
|
1293
|
-
}
|
|
1294
|
-
let propertyName = propertyStr;
|
|
1295
|
-
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1296
|
-
let storageObj = cs.args[1];
|
|
1297
|
-
this.addPropertyLinkEdge(propertyNode, storageObj, cid, cs.callStmt, Pag_1.StorageLinkEdgeType.Local2Property);
|
|
1298
|
-
}
|
|
1299
|
-
processStorageLink(cs, cid) {
|
|
1300
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1301
|
-
if (!propertyStr) {
|
|
1302
|
-
return;
|
|
1303
|
-
}
|
|
1304
|
-
let propertyName = propertyStr;
|
|
1305
|
-
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1306
|
-
let leftOp = cs.callStmt.getLeftOp();
|
|
1307
|
-
let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
|
|
1308
|
-
if (linkedOpNode instanceof Pag_1.PagLocalNode) {
|
|
1309
|
-
linkedOpNode.setStorageLink(Pag_1.StorageType.APP_STORAGE, propertyName);
|
|
1310
|
-
}
|
|
1311
|
-
this.pag.addPagEdge(propertyNode, linkedOpNode, Pag_1.PagEdgeKind.Copy);
|
|
1312
|
-
this.pag.addPagEdge(linkedOpNode, propertyNode, Pag_1.PagEdgeKind.Copy);
|
|
1313
|
-
}
|
|
1314
|
-
processStorageProp(cs, cid) {
|
|
1315
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1316
|
-
if (!propertyStr) {
|
|
1317
|
-
return;
|
|
1318
|
-
}
|
|
1319
|
-
let propertyName = propertyStr;
|
|
1320
|
-
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1321
|
-
let leftOp = cs.callStmt.getLeftOp();
|
|
1322
|
-
let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
|
|
1323
|
-
if (linkedOpNode instanceof Pag_1.PagLocalNode) {
|
|
1324
|
-
linkedOpNode.setStorageLink(Pag_1.StorageType.APP_STORAGE, propertyName);
|
|
1325
|
-
}
|
|
1326
|
-
this.pag.addPagEdge(propertyNode, linkedOpNode, Pag_1.PagEdgeKind.Copy);
|
|
1327
|
-
}
|
|
1328
|
-
processStorageSet(cs, cid) {
|
|
1329
|
-
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
1330
|
-
if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
1331
|
-
let base = ivkExpr.getBase();
|
|
1332
|
-
let baseNode = this.pag.getOrNewNode(cid, base);
|
|
1333
|
-
if (baseNode.isStorageLinked()) {
|
|
1334
|
-
let argsNode = this.pag.getOrNewNode(cid, cs.args[0]);
|
|
1335
|
-
this.pag.addPagEdge(argsNode, baseNode, Pag_1.PagEdgeKind.Copy);
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
else if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
1339
|
-
// TODO: process AppStorage.set()
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
processStorageGet(cs, cid) {
|
|
1343
|
-
if (!(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
|
|
1344
|
-
return;
|
|
1345
|
-
}
|
|
1346
|
-
let leftOp = cs.callStmt.getLeftOp();
|
|
1347
|
-
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
1348
|
-
let propertyName;
|
|
1349
|
-
if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
1350
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1351
|
-
if (propertyStr) {
|
|
1352
|
-
propertyName = propertyStr;
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
else if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
1356
|
-
let baseNode = this.pag.getOrNewNode(cid, ivkExpr.getBase());
|
|
1357
|
-
if (baseNode.isStorageLinked()) {
|
|
1358
|
-
propertyName = baseNode.getStorage().PropertyName;
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
let propertyNode = this.getPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1362
|
-
if (!propertyNode) {
|
|
1363
|
-
return;
|
|
1364
|
-
}
|
|
1365
|
-
this.pag.addPagEdge(propertyNode, this.pag.getOrNewNode(cid, leftOp, cs.callStmt), Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
1366
|
-
}
|
|
1367
|
-
getPropertyName(value) {
|
|
1368
|
-
if (value instanceof Local_1.Local) {
|
|
1369
|
-
let type = value.getType();
|
|
1370
|
-
if (type instanceof Type_1.StringType) {
|
|
1371
|
-
return type.getName();
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
else if (value instanceof Constant_1.Constant) {
|
|
1375
|
-
return value.getValue();
|
|
1376
|
-
}
|
|
1377
|
-
return undefined;
|
|
1378
|
-
}
|
|
1379
|
-
/**
|
|
1380
|
-
* get storageType enum with method's Declaring ClassName
|
|
1381
|
-
*
|
|
1382
|
-
* @param storageName ClassName that method belongs to, currently support AppStorage and SubscribedAbstractProperty
|
|
1383
|
-
* SubscribedAbstractProperty: in following listing, `link1` is infered as ClassType `SubscribedAbstractProperty`,
|
|
1384
|
-
* it needs to get PAG node to check the StorageType
|
|
1385
|
-
* let link1: SubscribedAbstractProperty<A> = AppStorage.link('PropA');
|
|
1386
|
-
* link1.set(a);
|
|
1387
|
-
* @param cs: for search PAG node in SubscribedAbstractProperty
|
|
1388
|
-
* @param cid: for search PAG node in SubscribedAbstractProperty
|
|
1389
|
-
* @returns StorageType enum
|
|
1390
|
-
*/
|
|
1391
|
-
getStorageType(storageName, cs, cid) {
|
|
1392
|
-
switch (storageName) {
|
|
1393
|
-
case 'AppStorage':
|
|
1394
|
-
return Pag_1.StorageType.APP_STORAGE;
|
|
1395
|
-
case 'SubscribedAbstractProperty': {
|
|
1396
|
-
let calleeBaseLocal = cs.callStmt.getInvokeExpr().getBase();
|
|
1397
|
-
let calleeBaseLocalNode = this.pag.getOrNewNode(cid, calleeBaseLocal);
|
|
1398
|
-
if (calleeBaseLocalNode.isStorageLinked()) {
|
|
1399
|
-
let storage = calleeBaseLocalNode.getStorage();
|
|
1400
|
-
return storage.StorageType;
|
|
1401
|
-
}
|
|
1402
|
-
return Pag_1.StorageType.Undefined;
|
|
1403
|
-
}
|
|
1404
|
-
default:
|
|
1405
|
-
return Pag_1.StorageType.Undefined;
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1408
994
|
/**\
|
|
1409
995
|
* ArkNewExpr, ArkNewArrayExpr, function ptr, globalThis
|
|
1410
996
|
*/
|
|
@@ -1656,25 +1242,6 @@ class PagBuilder {
|
|
|
1656
1242
|
resetUpdatedNodes() {
|
|
1657
1243
|
this.updatedNodesThisRound.clear();
|
|
1658
1244
|
}
|
|
1659
|
-
transferArrayValues(method, arrayLocal) {
|
|
1660
|
-
if (!(arrayLocal instanceof Local_1.Local) || !(arrayLocal.getType() instanceof Type_1.ArrayType)) {
|
|
1661
|
-
return [];
|
|
1662
|
-
}
|
|
1663
|
-
/**
|
|
1664
|
-
* TODO: get array element values
|
|
1665
|
-
* need to resolve multi dimension array
|
|
1666
|
-
*/
|
|
1667
|
-
const usedValuesInArray = arrayLocal.getUsedStmts().flatMap(stmt => {
|
|
1668
|
-
if (stmt instanceof Stmt_1.ArkAssignStmt) {
|
|
1669
|
-
const rightOp = stmt.getRightOp();
|
|
1670
|
-
if (rightOp instanceof Local_1.Local) {
|
|
1671
|
-
return rightOp;
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
return [];
|
|
1675
|
-
});
|
|
1676
|
-
return usedValuesInArray;
|
|
1677
|
-
}
|
|
1678
1245
|
getContextSelector() {
|
|
1679
1246
|
return this.ctxSelector;
|
|
1680
1247
|
}
|