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.
Files changed (78) hide show
  1. package/lib/Scene.d.ts +1 -2
  2. package/lib/Scene.d.ts.map +1 -1
  3. package/lib/Scene.js +59 -47
  4. package/lib/callgraph/pointerAnalysis/PTAUtils.d.ts +11 -5
  5. package/lib/callgraph/pointerAnalysis/PTAUtils.d.ts.map +1 -1
  6. package/lib/callgraph/pointerAnalysis/PTAUtils.js +42 -24
  7. package/lib/callgraph/pointerAnalysis/Pag.d.ts +6 -11
  8. package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
  9. package/lib/callgraph/pointerAnalysis/Pag.js +26 -23
  10. package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +11 -63
  11. package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
  12. package/lib/callgraph/pointerAnalysis/PagBuilder.js +62 -495
  13. package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
  14. package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +4 -2
  15. package/lib/callgraph/pointerAnalysis/plugins/ContainerPlugin.d.ts +24 -0
  16. package/lib/callgraph/pointerAnalysis/plugins/ContainerPlugin.d.ts.map +1 -0
  17. package/lib/callgraph/pointerAnalysis/plugins/ContainerPlugin.js +167 -0
  18. package/lib/callgraph/pointerAnalysis/plugins/FunctionPlugin.d.ts +26 -0
  19. package/lib/callgraph/pointerAnalysis/plugins/FunctionPlugin.d.ts.map +1 -0
  20. package/lib/callgraph/pointerAnalysis/plugins/FunctionPlugin.js +151 -0
  21. package/lib/callgraph/pointerAnalysis/plugins/IPagPlugin.d.ts +15 -0
  22. package/lib/callgraph/pointerAnalysis/plugins/IPagPlugin.d.ts.map +1 -0
  23. package/lib/callgraph/pointerAnalysis/plugins/IPagPlugin.js +16 -0
  24. package/lib/callgraph/pointerAnalysis/plugins/PluginManager.d.ts +25 -0
  25. package/lib/callgraph/pointerAnalysis/plugins/PluginManager.d.ts.map +1 -0
  26. package/lib/callgraph/pointerAnalysis/plugins/PluginManager.js +66 -0
  27. package/lib/callgraph/pointerAnalysis/plugins/SdkPlugin.d.ts +37 -0
  28. package/lib/callgraph/pointerAnalysis/plugins/SdkPlugin.d.ts.map +1 -0
  29. package/lib/callgraph/pointerAnalysis/plugins/SdkPlugin.js +160 -0
  30. package/lib/callgraph/pointerAnalysis/plugins/StoragePlugin.d.ts +68 -0
  31. package/lib/callgraph/pointerAnalysis/plugins/StoragePlugin.d.ts.map +1 -0
  32. package/lib/callgraph/pointerAnalysis/plugins/StoragePlugin.js +288 -0
  33. package/lib/core/common/DummyMainCreater.js +1 -1
  34. package/lib/core/common/IRInference.d.ts.map +1 -1
  35. package/lib/core/common/IRInference.js +4 -0
  36. package/lib/core/common/SdkUtils.d.ts +1 -1
  37. package/lib/core/common/SdkUtils.d.ts.map +1 -1
  38. package/lib/core/common/SdkUtils.js +18 -18
  39. package/lib/core/common/TypeInference.d.ts.map +1 -1
  40. package/lib/core/common/TypeInference.js +11 -2
  41. package/lib/core/graph/builder/CfgBuilder.js +1 -1
  42. package/lib/core/graph/builder/ConditionBuilder.js +1 -1
  43. package/lib/core/model/ArkClass.d.ts.map +1 -1
  44. package/lib/core/model/ArkClass.js +2 -1
  45. package/lib/core/model/builder/ArkMethodBuilder.d.ts +1 -0
  46. package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
  47. package/lib/core/model/builder/ArkMethodBuilder.js +40 -5
  48. package/lib/core/model/builder/BodyBuilder.js +1 -1
  49. package/lib/pass/Dispatcher.d.ts +2 -2
  50. package/lib/pass/Dispatcher.d.ts.map +1 -1
  51. package/lib/pass/Pass.d.ts +3 -3
  52. package/lib/pass/Pass.d.ts.map +1 -1
  53. package/lib/pass/ScenePassMgr.d.ts +4 -4
  54. package/lib/pass/ScenePassMgr.d.ts.map +1 -1
  55. package/lib/pass/validators/Exprs.d.ts +9 -0
  56. package/lib/pass/validators/Exprs.d.ts.map +1 -0
  57. package/lib/pass/validators/Exprs.js +40 -0
  58. package/lib/pass/validators/Models.d.ts +14 -0
  59. package/lib/pass/validators/Models.d.ts.map +1 -0
  60. package/lib/pass/validators/Models.js +42 -0
  61. package/lib/pass/validators/SceneValidator.d.ts +19 -0
  62. package/lib/pass/validators/SceneValidator.d.ts.map +1 -0
  63. package/lib/pass/validators/SceneValidator.js +77 -0
  64. package/lib/pass/validators/Stmts.d.ts +7 -0
  65. package/lib/pass/validators/Stmts.d.ts.map +1 -0
  66. package/lib/pass/validators/Stmts.js +36 -0
  67. package/lib/pass/{SceneValidator.d.ts → validators/Validator.d.ts} +100 -108
  68. package/lib/pass/validators/Validator.d.ts.map +1 -0
  69. package/lib/pass/{SceneValidator.js → validators/Validator.js} +147 -143
  70. package/lib/pass/validators/Values.d.ts +7 -0
  71. package/lib/pass/validators/Values.d.ts.map +1 -0
  72. package/lib/pass/validators/Values.js +34 -0
  73. package/lib/save/source/SourceStmt.js +1 -1
  74. package/lib/save/source/SourceTransformer.d.ts.map +1 -1
  75. package/lib/save/source/SourceTransformer.js +16 -1
  76. package/lib/utils/FileUtils.js +1 -1
  77. package/package.json +2 -2
  78. 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
- this.buildSDKFuncPag(funcID);
163
- return false;
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
- * will not create real funcPag, only create param values
228
+ * process Method level analysis only
232
229
  */
233
- buildSDKFuncPag(funcID) {
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
- if (type === 0) {
253
- // heapObj
254
- args.forEach((arg, index) => {
255
- let paramType = arg.getType();
256
- if (!(paramType instanceof Type_1.ClassType)) {
257
- return;
258
- // TODO: support more type
259
- }
260
- let argInstance = new Expr_1.ArkNewExpr(paramType);
261
- paramArr.set(index, argInstance);
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, this.fakeSdkMethodParamDeclaringStmt);
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, 0), 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
- // process the Storage API(Static)
346
- if (!this.processStorage(cs, calleeCGNode, cid)) {
347
- // If not Storage API, process normal edge
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, baseClassPTNode, calleeCid));
447
+ srcNodes.push(...this.addStaticPagCallReturnEdge(staticCS, cid, baseClassPTNode));
468
448
  continue;
469
449
  }
470
- if ((0, PTAUtils_1.getBuiltInApiType)(ivkExpr === null || ivkExpr === void 0 ? void 0 : ivkExpr.getMethodSignature()) === PTAUtils_1.BuiltApiType.NotBuiltIn) {
471
- srcNodes.push(...this.processNormalMethodPagCallEdge(staticCS, cid, calleeCid, baseClassPTNode));
472
- }
473
- else {
474
- // special SDK call: Container API, Function API
475
- srcNodes.push(...this.processBuiltInMethodPagCallEdge(staticCS, cid, calleeCid, baseClassPTNode));
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
- if (value instanceof Expr_1.ArkNewExpr) {
504
- // get class signature
505
- let clsSig = value.getType().getClassSignature();
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, calleeCid, baseClassPTNode) {
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
- srcNodes.push(...this.addSDKMethodPagCallEdge(cs, callerCid, calleeCid));
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.callStmt, callerCid, calleeCid, argsOffset));
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, callStmt, callerCid, calleeCid, offset) {
844
- var _a;
845
- let params = calleeMethod
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 (((_a = callStmt.getInvokeExpr()) === null || _a === void 0 ? void 0 : _a.getMethodSignature().getMethodSubSignature().getMethodName()) === 'forEach') {
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
- addStaticPagCallReturnEdge(cs, callerCid, calleeCid) {
941
- if (!calleeCid) {
942
- calleeCid = this.ctxSelector.selectContext(callerCid, cs, ContextSelector_1.emptyID, cs.calleeFuncID);
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, callerCid, calleeCid, calleeMethod));
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
  }