arkanalyzer 1.0.29 → 1.0.31
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 +7 -0
- package/lib/Scene.d.ts.map +1 -1
- package/lib/Scene.js +196 -173
- package/lib/VFG/builder/DVFGBuilder.d.ts.map +1 -1
- package/lib/VFG/builder/DVFGBuilder.js +11 -6
- package/lib/callgraph/algorithm/AbstractAnalysis.d.ts +3 -1
- package/lib/callgraph/algorithm/AbstractAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/AbstractAnalysis.js +18 -10
- package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/RapidTypeAnalysis.js +8 -7
- package/lib/callgraph/common/Statistics.d.ts.map +1 -1
- package/lib/callgraph/common/Statistics.js +25 -24
- package/lib/callgraph/model/CallGraph.d.ts.map +1 -1
- package/lib/callgraph/model/CallGraph.js +0 -1
- package/lib/callgraph/pointerAnalysis/Context.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Context.js +0 -1
- package/lib/callgraph/pointerAnalysis/PTAUtils.d.ts +9 -3
- package/lib/callgraph/pointerAnalysis/PTAUtils.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PTAUtils.js +32 -18
- package/lib/callgraph/pointerAnalysis/Pag.d.ts +17 -1
- package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Pag.js +74 -27
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +51 -18
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PagBuilder.js +533 -346
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +15 -14
- package/lib/core/base/Local.js +2 -2
- package/lib/core/base/Type.d.ts +10 -1
- package/lib/core/base/Type.d.ts.map +1 -1
- package/lib/core/base/Type.js +18 -1
- package/lib/core/common/ArkValueTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkValueTransformer.js +3 -1
- package/lib/core/common/DummyMainCreater.d.ts.map +1 -1
- package/lib/core/common/DummyMainCreater.js +17 -20
- package/lib/core/common/IRInference.d.ts.map +1 -1
- package/lib/core/common/IRInference.js +21 -12
- package/lib/core/common/TypeInference.d.ts +1 -0
- package/lib/core/common/TypeInference.d.ts.map +1 -1
- package/lib/core/common/TypeInference.js +30 -4
- package/lib/core/dataflow/DataflowSolver.d.ts +1 -0
- package/lib/core/dataflow/DataflowSolver.d.ts.map +1 -1
- package/lib/core/dataflow/DataflowSolver.js +21 -17
- package/lib/core/dataflow/ReachingDef.d.ts.map +1 -1
- package/lib/core/dataflow/ReachingDef.js +6 -0
- package/lib/core/dataflow/UndefinedVariable.d.ts.map +1 -1
- package/lib/core/dataflow/UndefinedVariable.js +0 -25
- package/lib/core/graph/Cfg.d.ts +1 -0
- package/lib/core/graph/Cfg.d.ts.map +1 -1
- package/lib/core/graph/Cfg.js +49 -45
- package/lib/core/graph/DominanceFinder.js +19 -19
- package/lib/core/graph/builder/ViewTreeBuilder.d.ts +1 -0
- package/lib/core/graph/builder/ViewTreeBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/ViewTreeBuilder.js +34 -31
- package/lib/core/model/ArkMethod.d.ts.map +1 -1
- package/lib/core/model/ArkMethod.js +13 -6
- package/lib/core/model/builder/builderUtils.d.ts.map +1 -1
- package/lib/core/model/builder/builderUtils.js +72 -63
- package/lib/save/serializeArkIR.d.ts.map +1 -1
- package/lib/save/serializeArkIR.js +11 -24
- package/lib/save/source/SourceBody.js +10 -10
- package/lib/save/source/SourceFilePrinter.d.ts +1 -0
- package/lib/save/source/SourceFilePrinter.d.ts.map +1 -1
- package/lib/save/source/SourceFilePrinter.js +11 -8
- package/lib/save/source/SourceNamespace.d.ts +1 -0
- package/lib/save/source/SourceNamespace.d.ts.map +1 -1
- package/lib/save/source/SourceNamespace.js +11 -8
- 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 +37 -35
- package/lib/save/source/SourceTransformer.d.ts +2 -0
- package/lib/save/source/SourceTransformer.d.ts.map +1 -1
- package/lib/save/source/SourceTransformer.js +64 -54
- package/lib/transformer/StaticSingleAssignmentFormer.d.ts +5 -0
- package/lib/transformer/StaticSingleAssignmentFormer.d.ts.map +1 -1
- package/lib/transformer/StaticSingleAssignmentFormer.js +119 -101
- package/lib/utils/CfgStructualAnalysis.d.ts +1 -0
- package/lib/utils/CfgStructualAnalysis.d.ts.map +1 -1
- package/lib/utils/CfgStructualAnalysis.js +28 -24
- package/lib/utils/FileUtils.d.ts.map +1 -1
- package/lib/utils/FileUtils.js +14 -12
- package/lib/utils/callGraphUtils.d.ts.map +1 -1
- package/lib/utils/callGraphUtils.js +26 -23
- package/lib/utils/entryMethodUtils.d.ts.map +1 -1
- package/lib/utils/entryMethodUtils.js +11 -8
- package/package.json +2 -2
|
@@ -81,6 +81,7 @@ class PagBuilder {
|
|
|
81
81
|
this.globalThisValue = new Local_1.Local(TSConst_1.GLOBAL_THIS_NAME);
|
|
82
82
|
this.storagePropertyMap = new Map();
|
|
83
83
|
this.externalScopeVariableMap = new Map();
|
|
84
|
+
this.retriggerNodesList = new Set();
|
|
84
85
|
this.pag = p;
|
|
85
86
|
this.cg = cg;
|
|
86
87
|
this.scale = scale;
|
|
@@ -154,9 +155,7 @@ class PagBuilder {
|
|
|
154
155
|
let fpag = new Pag_1.FuncPag();
|
|
155
156
|
for (let stmt of cfg.getStmts()) {
|
|
156
157
|
if (stmt instanceof Stmt_1.ArkAssignStmt) {
|
|
157
|
-
stmt.getRightOp()
|
|
158
|
-
this.handleValueFromExternalScope(v, funcID);
|
|
159
|
-
});
|
|
158
|
+
this.processExternalScopeValue(stmt.getRightOp(), funcID);
|
|
160
159
|
// Add non-call edges
|
|
161
160
|
let kind = this.getEdgeKindForAssignStmt(stmt);
|
|
162
161
|
if (kind !== Pag_1.PagEdgeKind.Unknown) {
|
|
@@ -167,6 +166,7 @@ class PagBuilder {
|
|
|
167
166
|
this.buildInvokeExprInAssignStmt(stmt, fpag);
|
|
168
167
|
}
|
|
169
168
|
else if (stmt instanceof Stmt_1.ArkInvokeStmt && this.scale === PointerAnalysisConfig_1.PtaAnalysisScale.WholeProgram) {
|
|
169
|
+
this.processExternalScopeValue(stmt.getInvokeExpr(), funcID);
|
|
170
170
|
this.buildInvokeExprInInvokeStmt(stmt, fpag);
|
|
171
171
|
}
|
|
172
172
|
else {
|
|
@@ -235,6 +235,16 @@ class PagBuilder {
|
|
|
235
235
|
throw new Error('Can not find callsite by stmt');
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
|
+
processExternalScopeValue(value, funcID) {
|
|
239
|
+
if (value instanceof Local_1.Local) {
|
|
240
|
+
this.handleValueFromExternalScope(value, funcID);
|
|
241
|
+
}
|
|
242
|
+
else if (value instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
243
|
+
value.getUses().forEach((v) => {
|
|
244
|
+
this.handleValueFromExternalScope(v, funcID);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
238
248
|
/**
|
|
239
249
|
* will not create real funcPag, only create param values
|
|
240
250
|
*/
|
|
@@ -306,7 +316,7 @@ class PagBuilder {
|
|
|
306
316
|
this.addEdgesFromInterFuncPag(interFuncPag, cid);
|
|
307
317
|
}
|
|
308
318
|
this.addCallsEdgesFromFuncPag(funcPag, cid);
|
|
309
|
-
this.addDynamicCallSite(funcPag, funcID);
|
|
319
|
+
this.addDynamicCallSite(funcPag, funcID, cid);
|
|
310
320
|
this.addUnknownCallSite(funcPag, funcID);
|
|
311
321
|
this.handledFunc.add(`${cid}-${funcID}`);
|
|
312
322
|
}
|
|
@@ -361,7 +371,7 @@ class PagBuilder {
|
|
|
361
371
|
if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
362
372
|
let baseNode = this.getOrNewPagNode(cid, ivkExpr.getBase());
|
|
363
373
|
let baseNodeID = baseNode.getID();
|
|
364
|
-
this.addThisRefCallEdge(baseNodeID, cid, ivkExpr, callee, calleeCid, cs.callerFuncID);
|
|
374
|
+
this.addThisRefCallEdge(baseNodeID, cid, ivkExpr.getBase(), callee, calleeCid, cs.callerFuncID);
|
|
365
375
|
}
|
|
366
376
|
else {
|
|
367
377
|
logger.error(`constructor or intrinsic func is static ${ivkExpr.toString()}`);
|
|
@@ -370,130 +380,7 @@ class PagBuilder {
|
|
|
370
380
|
}
|
|
371
381
|
return true;
|
|
372
382
|
}
|
|
373
|
-
|
|
374
|
-
* process Storage API
|
|
375
|
-
* @returns boolean: check if the cs represent a Storage API, no matter the API will success or fail
|
|
376
|
-
*/
|
|
377
|
-
processStorage(cs, calleeCGNode, cid) {
|
|
378
|
-
let storageName = calleeCGNode.getMethod().getDeclaringClassSignature().getClassName();
|
|
379
|
-
let storageType = this.getStorageType(storageName, cs, cid);
|
|
380
|
-
// TODO: add other storages
|
|
381
|
-
if (storageType === Pag_1.StorageType.APP_STORAGE) {
|
|
382
|
-
let calleeName = calleeCGNode.getMethod().getMethodSubSignature().getMethodName();
|
|
383
|
-
// TODO: complete AppStorage API
|
|
384
|
-
if (calleeName === 'setOrCreate') {
|
|
385
|
-
this.processStorageSetOrCreate(cs, cid);
|
|
386
|
-
}
|
|
387
|
-
else if (calleeName === 'link') {
|
|
388
|
-
this.processStorageLink(cs, cid);
|
|
389
|
-
}
|
|
390
|
-
else if (calleeName === 'prop') {
|
|
391
|
-
this.processStorageProp(cs, cid);
|
|
392
|
-
}
|
|
393
|
-
else if (calleeName === 'set') {
|
|
394
|
-
this.processStorageSet(cs, cid);
|
|
395
|
-
}
|
|
396
|
-
else if (calleeName === 'get') {
|
|
397
|
-
this.processStorageGet(cs, cid);
|
|
398
|
-
}
|
|
399
|
-
return true;
|
|
400
|
-
}
|
|
401
|
-
else if (storageType === Pag_1.StorageType.LOCAL_STORAGE) {
|
|
402
|
-
// TODO: LocalStorage is not Static
|
|
403
|
-
}
|
|
404
|
-
return false;
|
|
405
|
-
}
|
|
406
|
-
processStorageSetOrCreate(cs, cid) {
|
|
407
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
408
|
-
if (!propertyStr) {
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
let propertyName = propertyStr;
|
|
412
|
-
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
413
|
-
let storageObj = cs.args[1];
|
|
414
|
-
this.addPropertyLinkEdge(propertyNode, storageObj, cid, cs.callStmt, Pag_1.StorageLinkEdgeType.Local2Property);
|
|
415
|
-
}
|
|
416
|
-
processStorageLink(cs, cid) {
|
|
417
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
418
|
-
if (!propertyStr) {
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
let propertyName = propertyStr;
|
|
422
|
-
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
423
|
-
let leftOp = cs.callStmt.getLeftOp();
|
|
424
|
-
let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
|
|
425
|
-
if (linkedOpNode instanceof Pag_1.PagLocalNode) {
|
|
426
|
-
linkedOpNode.setStorageLink(Pag_1.StorageType.APP_STORAGE, propertyName);
|
|
427
|
-
}
|
|
428
|
-
this.pag.addPagEdge(propertyNode, linkedOpNode, Pag_1.PagEdgeKind.Copy);
|
|
429
|
-
this.pag.addPagEdge(linkedOpNode, propertyNode, Pag_1.PagEdgeKind.Copy);
|
|
430
|
-
}
|
|
431
|
-
processStorageProp(cs, cid) {
|
|
432
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
433
|
-
if (!propertyStr) {
|
|
434
|
-
return;
|
|
435
|
-
}
|
|
436
|
-
let propertyName = propertyStr;
|
|
437
|
-
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
438
|
-
let leftOp = cs.callStmt.getLeftOp();
|
|
439
|
-
let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
|
|
440
|
-
if (linkedOpNode instanceof Pag_1.PagLocalNode) {
|
|
441
|
-
linkedOpNode.setStorageLink(Pag_1.StorageType.APP_STORAGE, propertyName);
|
|
442
|
-
}
|
|
443
|
-
this.pag.addPagEdge(propertyNode, linkedOpNode, Pag_1.PagEdgeKind.Copy);
|
|
444
|
-
}
|
|
445
|
-
processStorageSet(cs, cid) {
|
|
446
|
-
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
447
|
-
if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
448
|
-
let base = ivkExpr.getBase();
|
|
449
|
-
let baseNode = this.pag.getOrNewNode(cid, base);
|
|
450
|
-
if (baseNode.isStorageLinked()) {
|
|
451
|
-
let argsNode = this.pag.getOrNewNode(cid, cs.args[0]);
|
|
452
|
-
this.pag.addPagEdge(argsNode, baseNode, Pag_1.PagEdgeKind.Copy);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
else if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
456
|
-
// TODO: process AppStorage.set()
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
processStorageGet(cs, cid) {
|
|
460
|
-
if (!(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
|
|
461
|
-
return;
|
|
462
|
-
}
|
|
463
|
-
let leftOp = cs.callStmt.getLeftOp();
|
|
464
|
-
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
465
|
-
let propertyName;
|
|
466
|
-
if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
467
|
-
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
468
|
-
if (propertyStr) {
|
|
469
|
-
propertyName = propertyStr;
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
else if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
473
|
-
let baseNode = this.pag.getOrNewNode(cid, ivkExpr.getBase());
|
|
474
|
-
if (baseNode.isStorageLinked()) {
|
|
475
|
-
propertyName = baseNode.getStorage().PropertyName;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
let propertyNode = this.getPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
479
|
-
if (!propertyNode) {
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
this.pag.addPagEdge(propertyNode, this.pag.getOrNewNode(cid, leftOp, cs.callStmt), Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
483
|
-
}
|
|
484
|
-
getPropertyName(value) {
|
|
485
|
-
if (value instanceof Local_1.Local) {
|
|
486
|
-
let type = value.getType();
|
|
487
|
-
if (type instanceof Type_1.StringType) {
|
|
488
|
-
return type.getName();
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
else if (value instanceof Constant_1.Constant) {
|
|
492
|
-
return value.getValue();
|
|
493
|
-
}
|
|
494
|
-
return undefined;
|
|
495
|
-
}
|
|
496
|
-
addDynamicCallSite(funcPag, funcID) {
|
|
383
|
+
addDynamicCallSite(funcPag, funcID, cid) {
|
|
497
384
|
// add dyn callsite in funcpag to base node
|
|
498
385
|
for (let cs of funcPag.getDynamicCallSites()) {
|
|
499
386
|
let invokeExpr = cs.callStmt.getInvokeExpr();
|
|
@@ -524,6 +411,9 @@ class PagBuilder {
|
|
|
524
411
|
}
|
|
525
412
|
node.addRelatedDynCallSite(cs);
|
|
526
413
|
}
|
|
414
|
+
if (cs.callStmt instanceof Stmt_1.ArkAssignStmt) {
|
|
415
|
+
this.getOrNewPagNode(cid, cs.callStmt.getLeftOp(), cs.callStmt);
|
|
416
|
+
}
|
|
527
417
|
}
|
|
528
418
|
}
|
|
529
419
|
addUnknownCallSite(funcPag, funcID) {
|
|
@@ -537,19 +427,20 @@ class PagBuilder {
|
|
|
537
427
|
var _a;
|
|
538
428
|
let calleeName = (_a = unknownCallSite.callStmt.getInvokeExpr()) === null || _a === void 0 ? void 0 : _a.getMethodSignature().getMethodSubSignature().getMethodName();
|
|
539
429
|
let base = locals.get(calleeName);
|
|
540
|
-
if (base) {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
430
|
+
if (!base) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
let baseNodeIDs = this.pag.getNodesByValue(base);
|
|
434
|
+
if (!baseNodeIDs) {
|
|
435
|
+
logger.warn(`[build dynamic call site] can not handle call site with base ${base.toString()}`);
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
for (let nodeID of baseNodeIDs.values()) {
|
|
439
|
+
let node = this.pag.getNode(nodeID);
|
|
440
|
+
if (!(node instanceof Pag_1.PagLocalNode)) {
|
|
441
|
+
continue;
|
|
552
442
|
}
|
|
443
|
+
node.addRelatedUnknownCallSite(unknownCallSite);
|
|
553
444
|
}
|
|
554
445
|
});
|
|
555
446
|
}
|
|
@@ -572,24 +463,29 @@ class PagBuilder {
|
|
|
572
463
|
// update call graph
|
|
573
464
|
// TODO: movo to cgbuilder
|
|
574
465
|
this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt);
|
|
575
|
-
if (
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
466
|
+
if (this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
|
|
467
|
+
return srcNodes;
|
|
468
|
+
}
|
|
469
|
+
let calleeCid = this.ctx.getOrNewContext(cid, dstCGNode.getID(), true);
|
|
470
|
+
let staticCS = new CallGraph_1.CallSite(cs.callStmt, cs.args, dstCGNode.getID(), cs.callerFuncID);
|
|
471
|
+
if (this.scale === PointerAnalysisConfig_1.PtaAnalysisScale.MethodLevel) {
|
|
472
|
+
srcNodes.push(...this.addStaticPagCallReturnEdge(staticCS, baseClassPTNode, calleeCid));
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
475
|
+
if ((0, PTAUtils_1.getBuiltInApiType)(ivkExpr === null || ivkExpr === void 0 ? void 0 : ivkExpr.getMethodSignature()) === PTAUtils_1.BuiltApiType.NotBuiltIn) {
|
|
476
|
+
srcNodes.push(...this.processNormalMethodPagCallEdge(staticCS, cid, calleeCid, baseClassPTNode));
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
// special SDK call: Container API, Function API
|
|
480
|
+
srcNodes.push(...this.processBuiltInMethodPagCallEdge(staticCS, cid, calleeCid, baseClassPTNode));
|
|
589
481
|
}
|
|
590
482
|
}
|
|
591
483
|
return srcNodes;
|
|
592
484
|
}
|
|
485
|
+
/**
|
|
486
|
+
* all possible callee methods of a dynamic call site
|
|
487
|
+
* handle both PtrInvokeExpr and InstanceInvokeExpr
|
|
488
|
+
*/
|
|
593
489
|
getDynamicCallee(ptNode, value, ivkExpr, cs) {
|
|
594
490
|
let callee = [];
|
|
595
491
|
if (ptNode instanceof Pag_1.PagFuncNode) {
|
|
@@ -599,58 +495,183 @@ class PagBuilder {
|
|
|
599
495
|
return callee;
|
|
600
496
|
}
|
|
601
497
|
callee.push(tempCallee);
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
498
|
+
return callee;
|
|
499
|
+
}
|
|
500
|
+
//else branch
|
|
501
|
+
let calleeName = ivkExpr.getMethodSignature().getMethodSubSignature().getMethodName();
|
|
502
|
+
// instance method invoke
|
|
503
|
+
if (!(value instanceof Expr_1.ArkNewExpr || value instanceof Expr_1.ArkNewArrayExpr)) {
|
|
504
|
+
return callee;
|
|
505
|
+
}
|
|
506
|
+
let tempCallee;
|
|
507
|
+
// try to get callee by MethodSignature
|
|
508
|
+
if (value instanceof Expr_1.ArkNewExpr) {
|
|
509
|
+
// get class signature
|
|
510
|
+
let clsSig = value.getType().getClassSignature();
|
|
511
|
+
let cls;
|
|
512
|
+
cls = this.scene.getClass(clsSig);
|
|
513
|
+
while (!tempCallee && cls) {
|
|
514
|
+
tempCallee = cls.getMethodWithName(calleeName);
|
|
515
|
+
cls = cls.getSuperClass();
|
|
516
|
+
}
|
|
517
|
+
if (!tempCallee) {
|
|
518
|
+
tempCallee = this.scene.getMethod(ivkExpr.getMethodSignature());
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
if (!tempCallee && cs.args) {
|
|
522
|
+
// while pts has {o_1, o_2} and invoke expr represents a method that only {o_1} has
|
|
523
|
+
// return empty node when {o_2} come in
|
|
524
|
+
// try to get callee by anonymous method in param
|
|
525
|
+
for (let arg of cs.args) {
|
|
526
|
+
// TODO: anonymous method param and return value pointer pass
|
|
527
|
+
let argType = arg.getType();
|
|
528
|
+
if (argType instanceof Type_1.FunctionType) {
|
|
529
|
+
callee.push(this.scene.getMethod(argType.getMethodSignature()));
|
|
622
530
|
}
|
|
623
531
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
532
|
+
}
|
|
533
|
+
else if (tempCallee) {
|
|
534
|
+
callee.push(tempCallee);
|
|
535
|
+
}
|
|
536
|
+
return callee;
|
|
537
|
+
}
|
|
538
|
+
processNormalMethodPagCallEdge(staticCS, cid, calleeCid, baseClassPTNode) {
|
|
539
|
+
let srcNodes = [];
|
|
540
|
+
let ivkExpr = staticCS.callStmt.getInvokeExpr();
|
|
541
|
+
let ptNode = this.pag.getNode(baseClassPTNode);
|
|
542
|
+
let dstCGNode = this.cg.getNode(staticCS.calleeFuncID);
|
|
543
|
+
let callee = this.cg.getArkMethodByFuncID(staticCS.calleeFuncID);
|
|
544
|
+
// Dynamic call, Ptr call, normal SDK call
|
|
545
|
+
srcNodes.push(...this.addStaticPagCallEdge(staticCS, cid, calleeCid, ptNode));
|
|
546
|
+
// Pass base's pts to callee's this pointer
|
|
547
|
+
if (!dstCGNode.isSdkMethod() && ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
548
|
+
let srcBaseNode = this.addThisRefCallEdge(baseClassPTNode, cid, ivkExpr.getBase(), callee, calleeCid, staticCS.callerFuncID);
|
|
549
|
+
srcNodes.push(srcBaseNode);
|
|
550
|
+
}
|
|
551
|
+
else if (!dstCGNode.isSdkMethod() && ivkExpr instanceof Expr_1.ArkPtrInvokeExpr) {
|
|
552
|
+
let thisValue = ptNode.getCS().args[0];
|
|
553
|
+
if (!(thisValue instanceof Local_1.Local)) {
|
|
554
|
+
return srcNodes;
|
|
635
555
|
}
|
|
636
|
-
|
|
637
|
-
|
|
556
|
+
this.addThisRefCallEdge(baseClassPTNode, ptNode.getOriginCid(), thisValue, callee, calleeCid, staticCS.callerFuncID);
|
|
557
|
+
}
|
|
558
|
+
return srcNodes;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* include container API, Function API
|
|
562
|
+
*/
|
|
563
|
+
processBuiltInMethodPagCallEdge(staticCS, cid, calleeCid, baseClassPTNode) {
|
|
564
|
+
let srcNodes = [];
|
|
565
|
+
let ivkExpr = staticCS.callStmt.getInvokeExpr();
|
|
566
|
+
let callee = this.scene.getMethod(ivkExpr.getMethodSignature());
|
|
567
|
+
let realCallee = this.cg.getArkMethodByFuncID(staticCS.calleeFuncID);
|
|
568
|
+
if (!callee) {
|
|
569
|
+
return srcNodes;
|
|
570
|
+
}
|
|
571
|
+
let builtInType = (0, PTAUtils_1.getBuiltInApiType)(callee.getSignature());
|
|
572
|
+
if (builtInType === PTAUtils_1.BuiltApiType.NotBuiltIn || !realCallee) {
|
|
573
|
+
return srcNodes;
|
|
574
|
+
}
|
|
575
|
+
switch (builtInType) {
|
|
576
|
+
case PTAUtils_1.BuiltApiType.SetAdd:
|
|
577
|
+
case PTAUtils_1.BuiltApiType.MapSet:
|
|
578
|
+
this.processContainerPagCallEdge(staticCS, cid, baseClassPTNode, builtInType);
|
|
579
|
+
break;
|
|
580
|
+
case PTAUtils_1.BuiltApiType.FunctionCall:
|
|
581
|
+
/**
|
|
582
|
+
* set this and param
|
|
583
|
+
* function.call(thisArg, arg1, arg2, ...)
|
|
584
|
+
*/
|
|
585
|
+
this.handleFunctionCall(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode);
|
|
586
|
+
break;
|
|
587
|
+
case PTAUtils_1.BuiltApiType.FunctionApply:
|
|
588
|
+
/**
|
|
589
|
+
* set this, resolve array param
|
|
590
|
+
* function.apply(thisArg, [argsArray])
|
|
591
|
+
*/
|
|
592
|
+
this.handleFunctionApply(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode);
|
|
593
|
+
break;
|
|
594
|
+
case PTAUtils_1.BuiltApiType.FunctionBind:
|
|
595
|
+
/**
|
|
596
|
+
* clone the function node and add the this pointer, origin callsite, args offset to it
|
|
597
|
+
* let f = function.bind(thisArg, arg1, arg2, ...)
|
|
598
|
+
* f();
|
|
599
|
+
*/
|
|
600
|
+
this.handleFunctionBind(staticCS, cid, baseClassPTNode, srcNodes);
|
|
601
|
+
break;
|
|
602
|
+
}
|
|
603
|
+
return srcNodes;
|
|
604
|
+
}
|
|
605
|
+
processContainerPagCallEdge(cs, cid, baseClassPTNode, type) {
|
|
606
|
+
let srcNodes = [];
|
|
607
|
+
let calleeNode = this.cg.getNode(cs.calleeFuncID);
|
|
608
|
+
let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
|
|
609
|
+
let ptNode = this.pag.getNode(baseClassPTNode);
|
|
610
|
+
if (!calleeMethod || !(ptNode instanceof Pag_1.PagNewContainerExprNode)) {
|
|
611
|
+
return srcNodes;
|
|
612
|
+
}
|
|
613
|
+
let containerValue = cs.callStmt.getInvokeExpr().getBase();
|
|
614
|
+
const containerValueProcess = (argIndex) => {
|
|
615
|
+
let srcNode = this.pag.getOrNewNode(cid, cs.args[argIndex], cs.callStmt);
|
|
616
|
+
let realContainerFieldPagNode = this.pag.getOrClonePagContainerFieldNode(baseClassPTNode, undefined, containerValue);
|
|
617
|
+
if (realContainerFieldPagNode) {
|
|
618
|
+
// In some cases, the value of a variable of array type may not be an explicit array object,
|
|
619
|
+
// and the value of `realContainerFieldPagNode` will be undefined.
|
|
620
|
+
this.pag.addPagEdge(srcNode, realContainerFieldPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
621
|
+
srcNodes.push(srcNode.getID());
|
|
638
622
|
}
|
|
623
|
+
};
|
|
624
|
+
if (type === PTAUtils_1.BuiltApiType.SetAdd) {
|
|
625
|
+
containerValueProcess(0);
|
|
639
626
|
}
|
|
640
|
-
|
|
627
|
+
else if (type === PTAUtils_1.BuiltApiType.MapSet) {
|
|
628
|
+
containerValueProcess(1);
|
|
629
|
+
}
|
|
630
|
+
return srcNodes;
|
|
641
631
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
updatedNode.union(diffPT);
|
|
647
|
-
this.updatedNodesThisRound.set(nodeID, updatedNode);
|
|
632
|
+
handleFunctionCall(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode) {
|
|
633
|
+
this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID));
|
|
634
|
+
srcNodes.push(...this.addCallParamPagEdge(realCallee, staticCS.args, staticCS.callStmt, cid, calleeCid, 1));
|
|
635
|
+
this.addThisEdge(staticCS, cid, realCallee, srcNodes, baseClassPTNode, calleeCid);
|
|
648
636
|
}
|
|
649
|
-
|
|
650
|
-
|
|
637
|
+
handleFunctionApply(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode) {
|
|
638
|
+
this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID));
|
|
639
|
+
let callerMethod = this.cg.getArkMethodByFuncID(staticCS.callerFuncID);
|
|
640
|
+
if (!callerMethod) {
|
|
641
|
+
throw new Error('Cannot get caller method');
|
|
642
|
+
}
|
|
643
|
+
let argsRealValues = this.transferArrayValues(callerMethod, staticCS.args[1]);
|
|
644
|
+
srcNodes.push(...this.addCallParamPagEdge(realCallee, argsRealValues, staticCS.callStmt, cid, calleeCid, 0));
|
|
645
|
+
this.addThisEdge(staticCS, cid, realCallee, srcNodes, baseClassPTNode, calleeCid);
|
|
651
646
|
}
|
|
652
|
-
|
|
653
|
-
this.
|
|
647
|
+
handleFunctionBind(staticCS, cid, baseClassPTNode, srcNodes) {
|
|
648
|
+
let srcNode = this.pag.getOrClonePagFuncNode(baseClassPTNode);
|
|
649
|
+
if (!srcNode) {
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
this.setFunctionThisPt(staticCS, srcNode, cid);
|
|
653
|
+
let dstNode = this.getOrNewPagNode(cid, staticCS.callStmt.getLeftOp());
|
|
654
|
+
this.pag.addPagEdge(srcNode, dstNode, Pag_1.PagEdgeKind.Copy, staticCS.callStmt);
|
|
655
|
+
srcNodes.push(srcNode.getID());
|
|
656
|
+
srcNode.setCS(staticCS);
|
|
657
|
+
srcNode.setArgsOffset(1);
|
|
658
|
+
srcNode.setOriginCid(cid);
|
|
659
|
+
}
|
|
660
|
+
addThisEdge(staticCS, cid, realCallee, srcNodes, baseClassPTNode, calleeCid) {
|
|
661
|
+
if (!(staticCS.args[0] instanceof Constant_1.NullConstant) && !(realCallee.isStatic())) {
|
|
662
|
+
srcNodes.push(this.addThisRefCallEdge(baseClassPTNode, cid, staticCS.args[0], realCallee, calleeCid, staticCS.callerFuncID));
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
setFunctionThisPt(staticCS, srcNode, cid) {
|
|
666
|
+
let thisLocal = staticCS.args[0];
|
|
667
|
+
if (!(thisLocal instanceof Local_1.Local)) {
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
let thisInstanceLocal = this.getRealThisLocal(thisLocal, staticCS.callerFuncID);
|
|
671
|
+
let baseThisNode = this.pag.getOrNewNode(cid, thisInstanceLocal);
|
|
672
|
+
for (let pt of baseThisNode.getPointTo()) {
|
|
673
|
+
srcNode.setThisPt(pt);
|
|
674
|
+
}
|
|
654
675
|
}
|
|
655
676
|
handleUnkownDynamicCall(cs, cid) {
|
|
656
677
|
var _a;
|
|
@@ -664,11 +685,12 @@ class PagBuilder {
|
|
|
664
685
|
callee = this.scene.getMethod(ivkExpr.getMethodSignature());
|
|
665
686
|
if (!callee) {
|
|
666
687
|
(_a = cs.args) === null || _a === void 0 ? void 0 : _a.forEach(arg => {
|
|
667
|
-
if (arg.getType() instanceof Type_1.FunctionType) {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
688
|
+
if (!(arg.getType() instanceof Type_1.FunctionType)) {
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
callee = this.scene.getMethod(arg.getType().getMethodSignature());
|
|
692
|
+
if (callee) {
|
|
693
|
+
callees.push(callee);
|
|
672
694
|
}
|
|
673
695
|
});
|
|
674
696
|
}
|
|
@@ -732,22 +754,10 @@ class PagBuilder {
|
|
|
732
754
|
}
|
|
733
755
|
return reAnalyzeNodes;
|
|
734
756
|
}
|
|
735
|
-
addThisRefCallEdge(baseClassPTNode, cid,
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
return -1;
|
|
740
|
-
}
|
|
741
|
-
let thisAssignStmt = (_a = callee.getCfg()) === null || _a === void 0 ? void 0 : _a.getStmts().filter(s => s instanceof Stmt_1.ArkAssignStmt && s.getRightOp() instanceof Ref_1.ArkThisRef);
|
|
742
|
-
let thisPtr = (thisAssignStmt === null || thisAssignStmt === void 0 ? void 0 : thisAssignStmt.at(0)).getRightOp();
|
|
743
|
-
if (!thisPtr) {
|
|
744
|
-
throw new Error('Can not get this ptr');
|
|
745
|
-
}
|
|
746
|
-
// IMPORTANT: set cid 2 base Pt info firstly
|
|
747
|
-
this.cid2ThisRefPtMap.set(calleeCid, baseClassPTNode);
|
|
748
|
-
let thisRefNode = this.getOrNewThisRefNode(calleeCid, thisPtr);
|
|
749
|
-
thisRefNode.addPTNode(baseClassPTNode);
|
|
750
|
-
let srcBaseLocal = ivkExpr.getBase();
|
|
757
|
+
addThisRefCallEdge(baseClassPTNode, cid, baseLocal, callee, calleeCid, callerFunID) {
|
|
758
|
+
let thisRefNodeID = this.recordThisRefNode(baseClassPTNode, callee, calleeCid);
|
|
759
|
+
let thisRefNode = this.pag.getNode(thisRefNodeID);
|
|
760
|
+
let srcBaseLocal = baseLocal;
|
|
751
761
|
srcBaseLocal = this.getRealThisLocal(srcBaseLocal, callerFunID);
|
|
752
762
|
let srcNodeId = this.pag.hasCtxNode(cid, srcBaseLocal);
|
|
753
763
|
if (!srcNodeId) {
|
|
@@ -764,12 +774,30 @@ class PagBuilder {
|
|
|
764
774
|
this.pag.addPagEdge(this.pag.getNode(srcNodeId), thisRefNode, Pag_1.PagEdgeKind.This);
|
|
765
775
|
return srcNodeId;
|
|
766
776
|
}
|
|
777
|
+
recordThisRefNode(baseClassPTNode, callee, calleeCid) {
|
|
778
|
+
var _a;
|
|
779
|
+
if (!callee || !callee.getCfg()) {
|
|
780
|
+
logger.error(`callee is null`);
|
|
781
|
+
return -1;
|
|
782
|
+
}
|
|
783
|
+
let thisAssignStmt = (_a = callee.getCfg()) === null || _a === void 0 ? void 0 : _a.getStmts().filter(s => s instanceof Stmt_1.ArkAssignStmt && s.getRightOp() instanceof Ref_1.ArkThisRef);
|
|
784
|
+
let thisPtr = (thisAssignStmt === null || thisAssignStmt === void 0 ? void 0 : thisAssignStmt.at(0)).getRightOp();
|
|
785
|
+
if (!thisPtr) {
|
|
786
|
+
throw new Error('Can not get this ptr');
|
|
787
|
+
}
|
|
788
|
+
// IMPORTANT: set cid 2 base Pt info firstly
|
|
789
|
+
this.cid2ThisRefPtMap.set(calleeCid, baseClassPTNode);
|
|
790
|
+
let thisRefNode = this.getOrNewThisRefNode(calleeCid, thisPtr);
|
|
791
|
+
thisRefNode.addPTNode(baseClassPTNode);
|
|
792
|
+
return thisRefNode.getID();
|
|
793
|
+
}
|
|
767
794
|
/*
|
|
768
795
|
* Add copy edges from arguments to parameters
|
|
769
796
|
* ret edges from return values to callsite
|
|
770
797
|
* Return src node
|
|
771
798
|
*/
|
|
772
|
-
addStaticPagCallEdge(cs, callerCid, calleeCid) {
|
|
799
|
+
addStaticPagCallEdge(cs, callerCid, calleeCid, ptNode) {
|
|
800
|
+
var _a, _b, _c, _d;
|
|
773
801
|
if (!calleeCid) {
|
|
774
802
|
calleeCid = this.ctx.getOrNewContext(callerCid, cs.calleeFuncID, true);
|
|
775
803
|
}
|
|
@@ -792,21 +820,100 @@ class PagBuilder {
|
|
|
792
820
|
let calleeCS = this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, cs.calleeFuncID));
|
|
793
821
|
// callee cid will updated if callee is singleton
|
|
794
822
|
calleeCid = calleeCS.cid;
|
|
795
|
-
|
|
823
|
+
let realArgs = (_a = cs.args) !== null && _a !== void 0 ? _a : [];
|
|
824
|
+
let argsOffset = 0;
|
|
825
|
+
if (ptNode && ptNode instanceof Pag_1.PagFuncNode && ptNode.getCS()) {
|
|
826
|
+
// for ptr invoke cloned by Function.bind()
|
|
827
|
+
realArgs = (_b = ptNode.getCS().args) !== null && _b !== void 0 ? _b : [];
|
|
828
|
+
argsOffset = (_c = ptNode.getArgsOffset()) !== null && _c !== void 0 ? _c : 0;
|
|
829
|
+
callerCid = (_d = ptNode.getOriginCid()) !== null && _d !== void 0 ? _d : callerCid;
|
|
830
|
+
}
|
|
831
|
+
srcNodes.push(...this.addCallParamPagEdge(calleeMethod, realArgs, cs.callStmt, callerCid, calleeCid, argsOffset));
|
|
832
|
+
srcNodes.push(...this.addCallReturnPagEdge(calleeMethod, cs.callStmt, callerCid, calleeCid));
|
|
833
|
+
return srcNodes;
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* only process the param PAG edge for invoke stmt
|
|
837
|
+
*/
|
|
838
|
+
addCallParamPagEdge(calleeMethod, args, callStmt, callerCid, calleeCid, offset) {
|
|
839
|
+
var _a;
|
|
796
840
|
let params = calleeMethod.getCfg().getStmts()
|
|
797
841
|
.filter(stmt => stmt instanceof Stmt_1.ArkAssignStmt && stmt.getRightOp() instanceof Ref_1.ArkParameterRef)
|
|
798
842
|
.map(stmt => stmt.getRightOp());
|
|
799
|
-
srcNodes
|
|
843
|
+
let srcNodes = [];
|
|
844
|
+
/**
|
|
845
|
+
* process foreach situation
|
|
846
|
+
* e.g. arr.forEach((item) => { ... })
|
|
847
|
+
* cs.args is anonymous method local, will have only 1 parameter
|
|
848
|
+
* but inside foreach will have >= 1 parameters
|
|
849
|
+
*/
|
|
850
|
+
if (((_a = callStmt.getInvokeExpr()) === null || _a === void 0 ? void 0 : _a.getMethodSignature().getMethodSubSignature().getMethodName()) === 'forEach') {
|
|
851
|
+
srcNodes.push(...this.addForeachParamPagEdge(callerCid, calleeCid, callStmt, params));
|
|
852
|
+
return srcNodes;
|
|
853
|
+
}
|
|
854
|
+
// add args to parameters edges
|
|
855
|
+
for (let i = offset; i <= args.length; i++) {
|
|
856
|
+
let arg = args.at(i);
|
|
857
|
+
let param = params.at(i - offset);
|
|
858
|
+
if (!arg || !param) {
|
|
859
|
+
return srcNodes;
|
|
860
|
+
}
|
|
861
|
+
if (arg instanceof Constant_1.Constant || arg instanceof Expr_1.AbstractExpr) {
|
|
862
|
+
// TODO: handle AbstractExpr
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
865
|
+
// Get or create new PAG node for argument and parameter
|
|
866
|
+
let srcPagNode = this.getOrNewPagNode(callerCid, arg, callStmt);
|
|
867
|
+
let dstPagNode = this.getOrNewPagNode(calleeCid, param, callStmt);
|
|
868
|
+
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, callStmt);
|
|
869
|
+
srcNodes.push(srcPagNode.getID());
|
|
870
|
+
// TODO: handle other types of parmeters
|
|
871
|
+
}
|
|
872
|
+
return srcNodes;
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* temporary solution for foreach
|
|
876
|
+
* deprecate when foreach is handled by built-in method
|
|
877
|
+
* connect the element node with the value inside foreach
|
|
878
|
+
*/
|
|
879
|
+
addForeachParamPagEdge(callerCid, calleeCid, callStmt, params) {
|
|
880
|
+
// container value is the base value of callstmt, its points-to is PagNewContainerExprNode
|
|
881
|
+
let srcNodes = [];
|
|
882
|
+
let containerValue = callStmt.getInvokeExpr().getBase();
|
|
883
|
+
let param = params.at(0);
|
|
884
|
+
if (!containerValue || !param) {
|
|
885
|
+
return srcNodes;
|
|
886
|
+
}
|
|
887
|
+
let basePagNode = this.getOrNewPagNode(callerCid, containerValue, callStmt);
|
|
888
|
+
let dstPagNode = this.getOrNewPagNode(calleeCid, param, callStmt);
|
|
889
|
+
for (let pt of basePagNode.getPointTo()) {
|
|
890
|
+
let newContainerExprPagNode = this.pag.getNode(pt);
|
|
891
|
+
// PagNewContainerExprNode's points-to is the element node
|
|
892
|
+
if (!newContainerExprPagNode || !newContainerExprPagNode.getElementNode()) {
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
let srcPagNode = this.pag.getNode(newContainerExprPagNode.getElementNode());
|
|
896
|
+
// connect the element node with the value inside foreach
|
|
897
|
+
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, callStmt);
|
|
898
|
+
srcNodes.push(srcPagNode.getID());
|
|
899
|
+
}
|
|
900
|
+
return srcNodes;
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* process the return value PAG edge for invoke stmt
|
|
904
|
+
*/
|
|
905
|
+
addCallReturnPagEdge(calleeMethod, callStmt, callerCid, calleeCid) {
|
|
906
|
+
let srcNodes = [];
|
|
800
907
|
// add ret to caller edges
|
|
801
908
|
let retStmts = calleeMethod.getReturnStmt();
|
|
802
909
|
// TODO: call statement must be a assignment state
|
|
803
|
-
if (
|
|
804
|
-
let retDst =
|
|
910
|
+
if (callStmt instanceof Stmt_1.ArkAssignStmt) {
|
|
911
|
+
let retDst = callStmt.getLeftOp();
|
|
805
912
|
for (let retStmt of retStmts) {
|
|
806
913
|
let retValue = retStmt.getOp();
|
|
807
914
|
if (retValue instanceof Local_1.Local) {
|
|
808
915
|
let srcPagNode = this.getOrNewPagNode(calleeCid, retValue, retStmt);
|
|
809
|
-
let dstPagNode = this.getOrNewPagNode(callerCid, retDst,
|
|
916
|
+
let dstPagNode = this.getOrNewPagNode(callerCid, retDst, callStmt);
|
|
810
917
|
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, retStmt);
|
|
811
918
|
}
|
|
812
919
|
else if (retValue instanceof Constant_1.Constant) {
|
|
@@ -838,62 +945,6 @@ class PagBuilder {
|
|
|
838
945
|
srcNodes.push(...this.addSDKMethodReturnPagEdge(cs, callerCid, calleeCid, calleeMethod));
|
|
839
946
|
return srcNodes;
|
|
840
947
|
}
|
|
841
|
-
addCallParamPagEdge(params, cs, callerCid, calleeCid) {
|
|
842
|
-
var _a, _b, _c;
|
|
843
|
-
let srcNodes = [];
|
|
844
|
-
let argNum = (_a = cs.args) === null || _a === void 0 ? void 0 : _a.length;
|
|
845
|
-
if (argNum === params.length) {
|
|
846
|
-
// add args to parameters edges
|
|
847
|
-
for (let i = 0; i < argNum; i++) {
|
|
848
|
-
let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b.at(i);
|
|
849
|
-
let param = params.at(i);
|
|
850
|
-
if (!arg || !param) {
|
|
851
|
-
return srcNodes;
|
|
852
|
-
}
|
|
853
|
-
if (arg instanceof Constant_1.Constant || arg instanceof Expr_1.AbstractExpr) {
|
|
854
|
-
// TODO: handle AbstractExpr
|
|
855
|
-
continue;
|
|
856
|
-
}
|
|
857
|
-
// Get or create new PAG node for argument and parameter
|
|
858
|
-
let srcPagNode = this.getOrNewPagNode(callerCid, arg, cs.callStmt);
|
|
859
|
-
let dstPagNode = this.getOrNewPagNode(calleeCid, param, cs.callStmt);
|
|
860
|
-
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
861
|
-
srcNodes.push(srcPagNode.getID());
|
|
862
|
-
// TODO: handle other types of parmeters
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
else {
|
|
866
|
-
/**
|
|
867
|
-
* process foreach situation
|
|
868
|
-
* e.g. arr.forEach((item) => { ... })
|
|
869
|
-
* cs.args is anonymous method local, will have only 1 parameter
|
|
870
|
-
* but inside foreach will have >= 1 parameters
|
|
871
|
-
*/
|
|
872
|
-
if (!(((_c = cs.callStmt.getInvokeExpr()) === null || _c === void 0 ? void 0 : _c.getMethodSignature().getMethodSubSignature().getMethodName()) === 'forEach')) {
|
|
873
|
-
return srcNodes;
|
|
874
|
-
}
|
|
875
|
-
// container value is the base value of callstmt, its points-to is PagNewContainerExprNode
|
|
876
|
-
let containerValue = cs.callStmt.getInvokeExpr().getBase();
|
|
877
|
-
let param = params.at(0);
|
|
878
|
-
if (!containerValue || !param) {
|
|
879
|
-
return srcNodes;
|
|
880
|
-
}
|
|
881
|
-
let basePagNode = this.getOrNewPagNode(callerCid, containerValue, cs.callStmt);
|
|
882
|
-
let dstPagNode = this.getOrNewPagNode(calleeCid, param, cs.callStmt);
|
|
883
|
-
for (let pt of basePagNode.getPointTo()) {
|
|
884
|
-
let newContainerExprPagNode = this.pag.getNode(pt);
|
|
885
|
-
// PagNewContainerExprNode's points-to is the element node
|
|
886
|
-
if (!newContainerExprPagNode || !newContainerExprPagNode.getElementNode()) {
|
|
887
|
-
continue;
|
|
888
|
-
}
|
|
889
|
-
let srcPagNode = this.pag.getNode(newContainerExprPagNode.getElementNode());
|
|
890
|
-
// connect the element node with the value inside foreach
|
|
891
|
-
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
892
|
-
srcNodes.push(srcPagNode.getID());
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
return srcNodes;
|
|
896
|
-
}
|
|
897
948
|
addSDKMethodPagCallEdge(cs, callerCid, calleeCid) {
|
|
898
949
|
let srcNodes = [];
|
|
899
950
|
let calleeNode = this.cg.getNode(cs.calleeFuncID);
|
|
@@ -901,8 +952,9 @@ class PagBuilder {
|
|
|
901
952
|
if (!calleeMethod) {
|
|
902
953
|
return srcNodes;
|
|
903
954
|
}
|
|
955
|
+
let methodType = (0, PTAUtils_1.getBuiltInApiType)(calleeMethod.getSignature());
|
|
904
956
|
// block the container SDK
|
|
905
|
-
if (
|
|
957
|
+
if (methodType === PTAUtils_1.BuiltApiType.SetAdd || PTAUtils_1.BuiltApiType.MapSet) {
|
|
906
958
|
return srcNodes;
|
|
907
959
|
}
|
|
908
960
|
if (!this.methodParamValueMap.has(calleeNode.getID())) {
|
|
@@ -941,70 +993,45 @@ class PagBuilder {
|
|
|
941
993
|
var _a, _b;
|
|
942
994
|
let argNum = (_a = cs.args) === null || _a === void 0 ? void 0 : _a.length;
|
|
943
995
|
let srcNodes = [];
|
|
944
|
-
if (argNum) {
|
|
945
|
-
// add args to parameters edges
|
|
946
|
-
for (let i = 0; i < argNum; i++) {
|
|
947
|
-
let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b.at(i);
|
|
948
|
-
let paramValue;
|
|
949
|
-
if (arg instanceof Local_1.Local && arg.getType() instanceof Type_1.FunctionType) {
|
|
950
|
-
// TODO: cannot find value
|
|
951
|
-
paramValue = this.methodParamValueMap.get(funcID).get(i);
|
|
952
|
-
}
|
|
953
|
-
else {
|
|
954
|
-
continue;
|
|
955
|
-
}
|
|
956
|
-
if (arg && paramValue) {
|
|
957
|
-
// Get or create new PAG node for argument and parameter
|
|
958
|
-
let srcPagNode = this.getOrNewPagNode(callerCid, arg, cs.callStmt);
|
|
959
|
-
let dstPagNode = this.getOrNewPagNode(calleeCid, paramValue, cs.callStmt);
|
|
960
|
-
if (dstPagNode instanceof Pag_1.PagLocalNode) {
|
|
961
|
-
// set the fake param Value in PagLocalNode
|
|
962
|
-
/**
|
|
963
|
-
* TODO: !!!
|
|
964
|
-
* some API param is in the form of anonymous method:
|
|
965
|
-
* component/common.d.ts
|
|
966
|
-
* declare function animateTo(value: AnimateParam, event: () => void): void;
|
|
967
|
-
*
|
|
968
|
-
* this param fake Value will create PagFuncNode rather than PagLocalNode
|
|
969
|
-
* when this API is called, the anonymous method pointer will not be able to pass into the fake Value PagNode
|
|
970
|
-
*/
|
|
971
|
-
dstPagNode.setSdkParam();
|
|
972
|
-
let sdkParamInvokeStmt = new Stmt_1.ArkInvokeStmt(new Expr_1.ArkPtrInvokeExpr(arg.getType().getMethodSignature(), paramValue, []));
|
|
973
|
-
// create new DynCallSite
|
|
974
|
-
let sdkParamCallSite = new CallGraph_1.DynCallSite(funcID, sdkParamInvokeStmt, undefined, undefined);
|
|
975
|
-
dstPagNode.addRelatedDynCallSite(sdkParamCallSite);
|
|
976
|
-
}
|
|
977
|
-
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
978
|
-
srcNodes.push(srcPagNode.getID());
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
return srcNodes;
|
|
983
|
-
}
|
|
984
|
-
processContainerPagCallEdge(cs, cid, baseClassPTNode) {
|
|
985
|
-
let srcNodes = [];
|
|
986
|
-
let calleeNode = this.cg.getNode(cs.calleeFuncID);
|
|
987
|
-
let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
|
|
988
|
-
let ptNode = this.pag.getNode(baseClassPTNode);
|
|
989
|
-
if (!calleeMethod || !(ptNode instanceof Pag_1.PagNewContainerExprNode)) {
|
|
996
|
+
if (!argNum) {
|
|
990
997
|
return srcNodes;
|
|
991
998
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
let
|
|
995
|
-
let
|
|
996
|
-
if (
|
|
997
|
-
//
|
|
998
|
-
|
|
999
|
-
this.pag.addPagEdge(srcNode, realContainerFieldPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
1000
|
-
srcNodes.push(srcNode.getID());
|
|
999
|
+
// add args to parameters edges
|
|
1000
|
+
for (let i = 0; i < argNum; i++) {
|
|
1001
|
+
let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b.at(i);
|
|
1002
|
+
let paramValue;
|
|
1003
|
+
if (arg instanceof Local_1.Local && arg.getType() instanceof Type_1.FunctionType) {
|
|
1004
|
+
// TODO: cannot find value
|
|
1005
|
+
paramValue = this.methodParamValueMap.get(funcID).get(i);
|
|
1001
1006
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1007
|
+
else {
|
|
1008
|
+
continue;
|
|
1009
|
+
}
|
|
1010
|
+
if (!(arg && paramValue)) {
|
|
1011
|
+
continue;
|
|
1012
|
+
}
|
|
1013
|
+
// Get or create new PAG node for argument and parameter
|
|
1014
|
+
let srcPagNode = this.getOrNewPagNode(callerCid, arg, cs.callStmt);
|
|
1015
|
+
let dstPagNode = this.getOrNewPagNode(calleeCid, paramValue, cs.callStmt);
|
|
1016
|
+
if (dstPagNode instanceof Pag_1.PagLocalNode) {
|
|
1017
|
+
// set the fake param Value in PagLocalNode
|
|
1018
|
+
/**
|
|
1019
|
+
* TODO: !!!
|
|
1020
|
+
* some API param is in the form of anonymous method:
|
|
1021
|
+
* component/common.d.ts
|
|
1022
|
+
* declare function animateTo(value: AnimateParam, event: () => void): void;
|
|
1023
|
+
*
|
|
1024
|
+
* this param fake Value will create PagFuncNode rather than PagLocalNode
|
|
1025
|
+
* when this API is called, the anonymous method pointer will not be able to pass into the fake Value PagNode
|
|
1026
|
+
*/
|
|
1027
|
+
dstPagNode.setSdkParam();
|
|
1028
|
+
let sdkParamInvokeStmt = new Stmt_1.ArkInvokeStmt(new Expr_1.ArkPtrInvokeExpr(arg.getType().getMethodSignature(), paramValue, []));
|
|
1029
|
+
// create new DynCallSite
|
|
1030
|
+
let sdkParamCallSite = new CallGraph_1.DynCallSite(funcID, sdkParamInvokeStmt, undefined, undefined);
|
|
1031
|
+
dstPagNode.addRelatedDynCallSite(sdkParamCallSite);
|
|
1032
|
+
}
|
|
1033
|
+
this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
1034
|
+
srcNodes.push(srcPagNode.getID());
|
|
1008
1035
|
}
|
|
1009
1036
|
return srcNodes;
|
|
1010
1037
|
}
|
|
@@ -1257,6 +1284,129 @@ class PagBuilder {
|
|
|
1257
1284
|
}
|
|
1258
1285
|
return Pag_1.PagEdgeKind.Unknown;
|
|
1259
1286
|
}
|
|
1287
|
+
/**
|
|
1288
|
+
* process Storage API
|
|
1289
|
+
* @returns boolean: check if the cs represent a Storage API, no matter the API will success or fail
|
|
1290
|
+
*/
|
|
1291
|
+
processStorage(cs, calleeCGNode, cid) {
|
|
1292
|
+
let storageName = calleeCGNode.getMethod().getDeclaringClassSignature().getClassName();
|
|
1293
|
+
let storageType = this.getStorageType(storageName, cs, cid);
|
|
1294
|
+
// TODO: add other storages
|
|
1295
|
+
if (storageType === Pag_1.StorageType.APP_STORAGE) {
|
|
1296
|
+
let calleeName = calleeCGNode.getMethod().getMethodSubSignature().getMethodName();
|
|
1297
|
+
// TODO: complete AppStorage API
|
|
1298
|
+
if (calleeName === 'setOrCreate') {
|
|
1299
|
+
this.processStorageSetOrCreate(cs, cid);
|
|
1300
|
+
}
|
|
1301
|
+
else if (calleeName === 'link') {
|
|
1302
|
+
this.processStorageLink(cs, cid);
|
|
1303
|
+
}
|
|
1304
|
+
else if (calleeName === 'prop') {
|
|
1305
|
+
this.processStorageProp(cs, cid);
|
|
1306
|
+
}
|
|
1307
|
+
else if (calleeName === 'set') {
|
|
1308
|
+
this.processStorageSet(cs, cid);
|
|
1309
|
+
}
|
|
1310
|
+
else if (calleeName === 'get') {
|
|
1311
|
+
this.processStorageGet(cs, cid);
|
|
1312
|
+
}
|
|
1313
|
+
return true;
|
|
1314
|
+
}
|
|
1315
|
+
else if (storageType === Pag_1.StorageType.LOCAL_STORAGE) {
|
|
1316
|
+
// TODO: LocalStorage is not Static
|
|
1317
|
+
}
|
|
1318
|
+
return false;
|
|
1319
|
+
}
|
|
1320
|
+
processStorageSetOrCreate(cs, cid) {
|
|
1321
|
+
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1322
|
+
if (!propertyStr) {
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
let propertyName = propertyStr;
|
|
1326
|
+
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1327
|
+
let storageObj = cs.args[1];
|
|
1328
|
+
this.addPropertyLinkEdge(propertyNode, storageObj, cid, cs.callStmt, Pag_1.StorageLinkEdgeType.Local2Property);
|
|
1329
|
+
}
|
|
1330
|
+
processStorageLink(cs, cid) {
|
|
1331
|
+
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1332
|
+
if (!propertyStr) {
|
|
1333
|
+
return;
|
|
1334
|
+
}
|
|
1335
|
+
let propertyName = propertyStr;
|
|
1336
|
+
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1337
|
+
let leftOp = cs.callStmt.getLeftOp();
|
|
1338
|
+
let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
|
|
1339
|
+
if (linkedOpNode instanceof Pag_1.PagLocalNode) {
|
|
1340
|
+
linkedOpNode.setStorageLink(Pag_1.StorageType.APP_STORAGE, propertyName);
|
|
1341
|
+
}
|
|
1342
|
+
this.pag.addPagEdge(propertyNode, linkedOpNode, Pag_1.PagEdgeKind.Copy);
|
|
1343
|
+
this.pag.addPagEdge(linkedOpNode, propertyNode, Pag_1.PagEdgeKind.Copy);
|
|
1344
|
+
}
|
|
1345
|
+
processStorageProp(cs, cid) {
|
|
1346
|
+
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1347
|
+
if (!propertyStr) {
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
let propertyName = propertyStr;
|
|
1351
|
+
let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1352
|
+
let leftOp = cs.callStmt.getLeftOp();
|
|
1353
|
+
let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
|
|
1354
|
+
if (linkedOpNode instanceof Pag_1.PagLocalNode) {
|
|
1355
|
+
linkedOpNode.setStorageLink(Pag_1.StorageType.APP_STORAGE, propertyName);
|
|
1356
|
+
}
|
|
1357
|
+
this.pag.addPagEdge(propertyNode, linkedOpNode, Pag_1.PagEdgeKind.Copy);
|
|
1358
|
+
}
|
|
1359
|
+
processStorageSet(cs, cid) {
|
|
1360
|
+
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
1361
|
+
if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
1362
|
+
let base = ivkExpr.getBase();
|
|
1363
|
+
let baseNode = this.pag.getOrNewNode(cid, base);
|
|
1364
|
+
if (baseNode.isStorageLinked()) {
|
|
1365
|
+
let argsNode = this.pag.getOrNewNode(cid, cs.args[0]);
|
|
1366
|
+
this.pag.addPagEdge(argsNode, baseNode, Pag_1.PagEdgeKind.Copy);
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
else if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
1370
|
+
// TODO: process AppStorage.set()
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
processStorageGet(cs, cid) {
|
|
1374
|
+
if (!(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
|
|
1375
|
+
return;
|
|
1376
|
+
}
|
|
1377
|
+
let leftOp = cs.callStmt.getLeftOp();
|
|
1378
|
+
let ivkExpr = cs.callStmt.getInvokeExpr();
|
|
1379
|
+
let propertyName;
|
|
1380
|
+
if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
|
|
1381
|
+
let propertyStr = this.getPropertyName(cs.args[0]);
|
|
1382
|
+
if (propertyStr) {
|
|
1383
|
+
propertyName = propertyStr;
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
else if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
|
|
1387
|
+
let baseNode = this.pag.getOrNewNode(cid, ivkExpr.getBase());
|
|
1388
|
+
if (baseNode.isStorageLinked()) {
|
|
1389
|
+
propertyName = baseNode.getStorage().PropertyName;
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
let propertyNode = this.getPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
|
|
1393
|
+
if (!propertyNode) {
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
this.pag.addPagEdge(propertyNode, this.pag.getOrNewNode(cid, leftOp, cs.callStmt), Pag_1.PagEdgeKind.Copy, cs.callStmt);
|
|
1397
|
+
}
|
|
1398
|
+
getPropertyName(value) {
|
|
1399
|
+
if (value instanceof Local_1.Local) {
|
|
1400
|
+
let type = value.getType();
|
|
1401
|
+
if (type instanceof Type_1.StringType) {
|
|
1402
|
+
return type.getName();
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
else if (value instanceof Constant_1.Constant) {
|
|
1406
|
+
return value.getValue();
|
|
1407
|
+
}
|
|
1408
|
+
return undefined;
|
|
1409
|
+
}
|
|
1260
1410
|
/**
|
|
1261
1411
|
* get storageType enum with method's Declaring ClassName
|
|
1262
1412
|
*
|
|
@@ -1387,7 +1537,7 @@ class PagBuilder {
|
|
|
1387
1537
|
*/
|
|
1388
1538
|
handleValueFromExternalScope(value, funcID, originValue) {
|
|
1389
1539
|
if (value instanceof Local_1.Local) {
|
|
1390
|
-
if (value.getDeclaringStmt()) {
|
|
1540
|
+
if (value.getDeclaringStmt() || (value.getName() === 'this')) {
|
|
1391
1541
|
// not from external scope
|
|
1392
1542
|
return;
|
|
1393
1543
|
}
|
|
@@ -1435,7 +1585,6 @@ class PagBuilder {
|
|
|
1435
1585
|
}
|
|
1436
1586
|
getSourceValueFromExternalScope(value, funcID) {
|
|
1437
1587
|
let sourceValue;
|
|
1438
|
-
// TODO: first from default method
|
|
1439
1588
|
sourceValue = this.getDefaultMethodSourceValue(value, funcID);
|
|
1440
1589
|
if (!sourceValue) {
|
|
1441
1590
|
sourceValue = this.getExportSourceValue(value, funcID);
|
|
@@ -1512,9 +1661,47 @@ class PagBuilder {
|
|
|
1512
1661
|
let existingNodes = this.pag.getNodesByValue(exportLocal);
|
|
1513
1662
|
existingNodes === null || existingNodes === void 0 ? void 0 : existingNodes.forEach(n => {
|
|
1514
1663
|
this.pag.addPagEdge(this.pag.getNode(n), dstPagNode, e.kind);
|
|
1664
|
+
this.retriggerNodesList.add(n);
|
|
1515
1665
|
});
|
|
1516
1666
|
}
|
|
1517
1667
|
return true;
|
|
1518
1668
|
}
|
|
1669
|
+
getRetriggerNodes() {
|
|
1670
|
+
let retriggerNodes = Array.from(this.retriggerNodesList);
|
|
1671
|
+
this.retriggerNodesList.clear();
|
|
1672
|
+
return retriggerNodes;
|
|
1673
|
+
}
|
|
1674
|
+
addUpdatedNode(nodeID, diffPT) {
|
|
1675
|
+
var _a;
|
|
1676
|
+
let ptaConfig = PointerAnalysisConfig_1.PointerAnalysisConfig.getInstance();
|
|
1677
|
+
let updatedNode = (_a = this.updatedNodesThisRound.get(nodeID)) !== null && _a !== void 0 ? _a : new ptaConfig.ptsCollectionCtor();
|
|
1678
|
+
updatedNode.union(diffPT);
|
|
1679
|
+
this.updatedNodesThisRound.set(nodeID, updatedNode);
|
|
1680
|
+
}
|
|
1681
|
+
getUpdatedNodes() {
|
|
1682
|
+
return this.updatedNodesThisRound;
|
|
1683
|
+
}
|
|
1684
|
+
resetUpdatedNodes() {
|
|
1685
|
+
this.updatedNodesThisRound.clear();
|
|
1686
|
+
}
|
|
1687
|
+
transferArrayValues(method, arrayLocal) {
|
|
1688
|
+
if (!(arrayLocal instanceof Local_1.Local) || !(arrayLocal.getType() instanceof Type_1.ArrayType)) {
|
|
1689
|
+
return [];
|
|
1690
|
+
}
|
|
1691
|
+
/**
|
|
1692
|
+
* TODO: get array element values
|
|
1693
|
+
* need to resolve multi dimension array
|
|
1694
|
+
*/
|
|
1695
|
+
const usedValuesInArray = arrayLocal.getUsedStmts().flatMap(stmt => {
|
|
1696
|
+
if (stmt instanceof Stmt_1.ArkAssignStmt) {
|
|
1697
|
+
const rightOp = stmt.getRightOp();
|
|
1698
|
+
if (rightOp instanceof Local_1.Local) {
|
|
1699
|
+
return rightOp;
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
return [];
|
|
1703
|
+
});
|
|
1704
|
+
return usedValuesInArray;
|
|
1705
|
+
}
|
|
1519
1706
|
}
|
|
1520
1707
|
exports.PagBuilder = PagBuilder;
|