arkanalyzer 1.0.6 → 1.0.8

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 (224) hide show
  1. package/config/arkanalyzer.json +8 -0
  2. package/docs/IR2ts-stmt.md +81 -0
  3. package/docs/IR2ts.md +82 -0
  4. package/lib/Config.d.ts +29 -1
  5. package/lib/Config.d.ts.map +1 -1
  6. package/lib/Config.js +44 -11
  7. package/lib/Scene.d.ts +152 -9
  8. package/lib/Scene.d.ts.map +1 -1
  9. package/lib/Scene.js +233 -66
  10. package/lib/callgraph/algorithm/AbstractAnalysis.d.ts +2 -1
  11. package/lib/callgraph/algorithm/AbstractAnalysis.d.ts.map +1 -1
  12. package/lib/callgraph/algorithm/AbstractAnalysis.js +14 -7
  13. package/lib/callgraph/algorithm/ClassHierarchyAnalysis.d.ts.map +1 -1
  14. package/lib/callgraph/algorithm/ClassHierarchyAnalysis.js +2 -4
  15. package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts.map +1 -1
  16. package/lib/callgraph/algorithm/RapidTypeAnalysis.js +2 -3
  17. package/lib/callgraph/common/Statistics.js +1 -1
  18. package/lib/callgraph/model/BaseGraph.js +2 -2
  19. package/lib/callgraph/model/CallGraph.d.ts +3 -2
  20. package/lib/callgraph/model/CallGraph.d.ts.map +1 -1
  21. package/lib/callgraph/model/CallGraph.js +23 -14
  22. package/lib/callgraph/model/builder/CallGraphBuilder.d.ts +2 -2
  23. package/lib/callgraph/model/builder/CallGraphBuilder.js +3 -3
  24. package/lib/callgraph/pointerAnalysis/Context.d.ts.map +1 -1
  25. package/lib/callgraph/pointerAnalysis/Context.js +0 -1
  26. package/lib/callgraph/pointerAnalysis/Pag.d.ts +36 -9
  27. package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
  28. package/lib/callgraph/pointerAnalysis/Pag.js +130 -37
  29. package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +34 -5
  30. package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
  31. package/lib/callgraph/pointerAnalysis/PagBuilder.js +479 -126
  32. package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts +6 -0
  33. package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
  34. package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +107 -45
  35. package/lib/callgraph/pointerAnalysis/PtsDS.d.ts.map +1 -1
  36. package/lib/callgraph/pointerAnalysis/PtsDS.js +0 -2
  37. package/lib/core/base/Constant.d.ts +37 -5
  38. package/lib/core/base/Constant.d.ts.map +1 -1
  39. package/lib/core/base/Constant.js +58 -8
  40. package/lib/core/base/Expr.d.ts +98 -13
  41. package/lib/core/base/Expr.d.ts.map +1 -1
  42. package/lib/core/base/Expr.js +295 -127
  43. package/lib/core/base/Local.d.ts +70 -5
  44. package/lib/core/base/Local.d.ts.map +1 -1
  45. package/lib/core/base/Local.js +77 -4
  46. package/lib/core/base/Ref.d.ts +79 -5
  47. package/lib/core/base/Ref.d.ts.map +1 -1
  48. package/lib/core/base/Ref.js +143 -38
  49. package/lib/core/base/Stmt.d.ts +126 -12
  50. package/lib/core/base/Stmt.d.ts.map +1 -1
  51. package/lib/core/base/Stmt.js +135 -28
  52. package/lib/core/base/Type.d.ts +11 -2
  53. package/lib/core/base/Type.d.ts.map +1 -1
  54. package/lib/core/base/Type.js +47 -42
  55. package/lib/core/base/Value.d.ts +24 -2
  56. package/lib/core/base/Value.d.ts.map +1 -1
  57. package/lib/core/common/ArkError.d.ts +15 -0
  58. package/lib/core/common/ArkError.d.ts.map +1 -0
  59. package/lib/core/common/ArkError.js +28 -0
  60. package/lib/core/common/ArkIRTransformer.d.ts +12 -5
  61. package/lib/core/common/ArkIRTransformer.d.ts.map +1 -1
  62. package/lib/core/common/ArkIRTransformer.js +90 -45
  63. package/lib/core/common/BodyBuilder.d.ts +2 -0
  64. package/lib/core/common/BodyBuilder.d.ts.map +1 -1
  65. package/lib/core/common/BodyBuilder.js +5 -2
  66. package/lib/core/common/Builtin.js +1 -1
  67. package/lib/core/common/CfgBuilder.d.ts +12 -7
  68. package/lib/core/common/CfgBuilder.d.ts.map +1 -1
  69. package/lib/core/common/CfgBuilder.js +336 -140
  70. package/lib/core/common/Const.d.ts +15 -10
  71. package/lib/core/common/Const.d.ts.map +1 -1
  72. package/lib/core/common/Const.js +18 -11
  73. package/lib/core/common/DummyMainCreater.d.ts +5 -4
  74. package/lib/core/common/DummyMainCreater.d.ts.map +1 -1
  75. package/lib/core/common/DummyMainCreater.js +43 -28
  76. package/lib/core/common/EtsConst.d.ts +1 -0
  77. package/lib/core/common/EtsConst.d.ts.map +1 -1
  78. package/lib/core/common/EtsConst.js +2 -1
  79. package/lib/core/common/ExprUseReplacer.js +8 -8
  80. package/lib/core/common/IRUtils.d.ts +7 -0
  81. package/lib/core/common/IRUtils.d.ts.map +1 -1
  82. package/lib/core/common/IRUtils.js +34 -2
  83. package/lib/core/common/ModelUtils.d.ts +1 -0
  84. package/lib/core/common/ModelUtils.d.ts.map +1 -1
  85. package/lib/core/common/ModelUtils.js +39 -36
  86. package/lib/core/common/RefUseReplacer.js +3 -3
  87. package/lib/core/common/StmtUseReplacer.js +4 -4
  88. package/lib/core/common/TSConst.d.ts +10 -3
  89. package/lib/core/common/TSConst.d.ts.map +1 -1
  90. package/lib/core/common/TSConst.js +11 -4
  91. package/lib/core/common/TypeInference.d.ts +8 -2
  92. package/lib/core/common/TypeInference.d.ts.map +1 -1
  93. package/lib/core/common/TypeInference.js +222 -90
  94. package/lib/core/common/ValueUtil.d.ts +0 -4
  95. package/lib/core/common/ValueUtil.d.ts.map +1 -1
  96. package/lib/core/common/ValueUtil.js +10 -27
  97. package/lib/core/common/VisibleValue.js +1 -1
  98. package/lib/core/dataflow/DataflowProblem.d.ts +1 -0
  99. package/lib/core/dataflow/DataflowProblem.d.ts.map +1 -1
  100. package/lib/core/dataflow/DataflowProblem.js +4 -4
  101. package/lib/core/dataflow/DataflowSolver.d.ts +20 -16
  102. package/lib/core/dataflow/DataflowSolver.d.ts.map +1 -1
  103. package/lib/core/dataflow/DataflowSolver.js +67 -78
  104. package/lib/core/dataflow/TiantAnalysis.d.ts +1 -0
  105. package/lib/core/dataflow/TiantAnalysis.d.ts.map +1 -1
  106. package/lib/core/dataflow/TiantAnalysis.js +42 -28
  107. package/lib/core/dataflow/UndefinedVariable.d.ts +15 -1
  108. package/lib/core/dataflow/UndefinedVariable.d.ts.map +1 -1
  109. package/lib/core/dataflow/UndefinedVariable.js +122 -76
  110. package/lib/core/dataflow/Util.d.ts +5 -1
  111. package/lib/core/dataflow/Util.d.ts.map +1 -1
  112. package/lib/core/dataflow/Util.js +43 -22
  113. package/lib/core/graph/BasicBlock.d.ts +72 -0
  114. package/lib/core/graph/BasicBlock.d.ts.map +1 -1
  115. package/lib/core/graph/BasicBlock.js +165 -3
  116. package/lib/core/graph/Cfg.d.ts +30 -1
  117. package/lib/core/graph/Cfg.d.ts.map +1 -1
  118. package/lib/core/graph/Cfg.js +131 -11
  119. package/lib/core/graph/DominanceFinder.js +7 -7
  120. package/lib/core/graph/DominanceTree.js +4 -4
  121. package/lib/core/graph/builder/ViewTreeBuilder.d.ts.map +1 -1
  122. package/lib/core/graph/builder/ViewTreeBuilder.js +6 -5
  123. package/lib/core/model/ArkBaseModel.d.ts +59 -0
  124. package/lib/core/model/ArkBaseModel.d.ts.map +1 -0
  125. package/lib/core/model/ArkBaseModel.js +271 -0
  126. package/lib/core/model/ArkBody.d.ts +3 -9
  127. package/lib/core/model/ArkBody.d.ts.map +1 -1
  128. package/lib/core/model/ArkBody.js +3 -14
  129. package/lib/core/model/ArkClass.d.ts +107 -13
  130. package/lib/core/model/ArkClass.d.ts.map +1 -1
  131. package/lib/core/model/ArkClass.js +152 -54
  132. package/lib/core/model/ArkExport.d.ts +8 -7
  133. package/lib/core/model/ArkExport.d.ts.map +1 -1
  134. package/lib/core/model/ArkExport.js +16 -18
  135. package/lib/core/model/ArkField.d.ts +16 -13
  136. package/lib/core/model/ArkField.d.ts.map +1 -1
  137. package/lib/core/model/ArkField.js +18 -62
  138. package/lib/core/model/ArkFile.d.ts +42 -0
  139. package/lib/core/model/ArkFile.d.ts.map +1 -1
  140. package/lib/core/model/ArkFile.js +58 -0
  141. package/lib/core/model/ArkImport.d.ts +9 -7
  142. package/lib/core/model/ArkImport.d.ts.map +1 -1
  143. package/lib/core/model/ArkImport.js +11 -12
  144. package/lib/core/model/ArkMetadata.d.ts +20 -0
  145. package/lib/core/model/ArkMetadata.d.ts.map +1 -0
  146. package/lib/core/model/ArkMetadata.js +44 -0
  147. package/lib/core/model/ArkMethod.d.ts +195 -17
  148. package/lib/core/model/ArkMethod.d.ts.map +1 -1
  149. package/lib/core/model/ArkMethod.js +363 -46
  150. package/lib/core/model/ArkNamespace.d.ts +6 -8
  151. package/lib/core/model/ArkNamespace.d.ts.map +1 -1
  152. package/lib/core/model/ArkNamespace.js +16 -20
  153. package/lib/core/model/ArkSignature.d.ts +41 -0
  154. package/lib/core/model/ArkSignature.d.ts.map +1 -1
  155. package/lib/core/model/ArkSignature.js +76 -19
  156. package/lib/core/model/builder/ArkClassBuilder.d.ts.map +1 -1
  157. package/lib/core/model/builder/ArkClassBuilder.js +60 -49
  158. package/lib/core/model/builder/ArkExportBuilder.d.ts.map +1 -1
  159. package/lib/core/model/builder/ArkExportBuilder.js +12 -6
  160. package/lib/core/model/builder/ArkFieldBuilder.d.ts.map +1 -1
  161. package/lib/core/model/builder/ArkFieldBuilder.js +13 -9
  162. package/lib/core/model/builder/ArkFileBuilder.js +1 -3
  163. package/lib/core/model/builder/ArkImportBuilder.d.ts +2 -1
  164. package/lib/core/model/builder/ArkImportBuilder.d.ts.map +1 -1
  165. package/lib/core/model/builder/ArkImportBuilder.js +16 -13
  166. package/lib/core/model/builder/ArkMethodBuilder.d.ts +3 -1
  167. package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
  168. package/lib/core/model/builder/ArkMethodBuilder.js +105 -45
  169. package/lib/core/model/builder/ArkNamespaceBuilder.d.ts.map +1 -1
  170. package/lib/core/model/builder/ArkNamespaceBuilder.js +4 -5
  171. package/lib/core/model/builder/builderUtils.d.ts +2 -1
  172. package/lib/core/model/builder/builderUtils.d.ts.map +1 -1
  173. package/lib/core/model/builder/builderUtils.js +63 -43
  174. package/lib/index.d.ts +2 -1
  175. package/lib/index.d.ts.map +1 -1
  176. package/lib/index.js +4 -3
  177. package/lib/save/ArkStream.js +1 -1
  178. package/lib/save/DotPrinter.d.ts.map +1 -1
  179. package/lib/save/DotPrinter.js +1 -15
  180. package/lib/save/GraphPrinter.d.ts.map +1 -1
  181. package/lib/save/GraphPrinter.js +4 -2
  182. package/lib/save/JsonPrinter.js +5 -5
  183. package/lib/save/ViewTreePrinter.d.ts +16 -0
  184. package/lib/save/ViewTreePrinter.d.ts.map +1 -0
  185. package/lib/save/ViewTreePrinter.js +130 -0
  186. package/lib/save/source/SourceBase.d.ts +2 -2
  187. package/lib/save/source/SourceBase.d.ts.map +1 -1
  188. package/lib/save/source/SourceBase.js +6 -13
  189. package/lib/save/source/SourceBody.d.ts.map +1 -1
  190. package/lib/save/source/SourceBody.js +27 -14
  191. package/lib/save/source/SourceClass.d.ts.map +1 -1
  192. package/lib/save/source/SourceClass.js +12 -8
  193. package/lib/save/source/SourceField.d.ts.map +1 -1
  194. package/lib/save/source/SourceField.js +6 -2
  195. package/lib/save/source/SourceMethod.d.ts.map +1 -1
  196. package/lib/save/source/SourceMethod.js +10 -3
  197. package/lib/save/source/SourceModule.d.ts.map +1 -1
  198. package/lib/save/source/SourceModule.js +16 -10
  199. package/lib/save/source/SourceNamespace.d.ts.map +1 -1
  200. package/lib/save/source/SourceNamespace.js +4 -0
  201. package/lib/save/source/SourceStmt.d.ts +1 -1
  202. package/lib/save/source/SourceStmt.d.ts.map +1 -1
  203. package/lib/save/source/SourceStmt.js +37 -25
  204. package/lib/save/source/SourceTransformer.d.ts +6 -0
  205. package/lib/save/source/SourceTransformer.d.ts.map +1 -1
  206. package/lib/save/source/SourceTransformer.js +82 -51
  207. package/lib/save/source/SourceUtils.d.ts.map +1 -1
  208. package/lib/save/source/SourceUtils.js +12 -11
  209. package/lib/transformer/StaticSingleAssignmentFormer.js +3 -3
  210. package/lib/utils/CfgStructualAnalysis.d.ts +1 -0
  211. package/lib/utils/CfgStructualAnalysis.d.ts.map +1 -1
  212. package/lib/utils/CfgStructualAnalysis.js +103 -72
  213. package/lib/utils/callGraphUtils.d.ts.map +1 -1
  214. package/lib/utils/callGraphUtils.js +7 -10
  215. package/lib/utils/crypto_utils.d.ts +6 -0
  216. package/lib/utils/crypto_utils.d.ts.map +1 -0
  217. package/lib/utils/crypto_utils.js +57 -0
  218. package/lib/utils/entryMethodUtils.d.ts.map +1 -1
  219. package/lib/utils/entryMethodUtils.js +27 -26
  220. package/lib/utils/getAllFiles.d.ts +1 -1
  221. package/lib/utils/getAllFiles.d.ts.map +1 -1
  222. package/lib/utils/getAllFiles.js +4 -5
  223. package/lib/utils/logger.js +2 -2
  224. package/package.json +3 -2
@@ -51,6 +51,7 @@ const Context_1 = require("./Context");
51
51
  const Pag_1 = require("./Pag");
52
52
  const PtsDS_1 = require("./PtsDS");
53
53
  const TSConst_1 = require("../../core/common/TSConst");
54
+ const Const_1 = require("../../core/common/Const");
54
55
  const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'PTA');
55
56
  class CSFuncID {
56
57
  constructor(cid, fid) {
@@ -70,10 +71,15 @@ class PagBuilder {
70
71
  this.cid2ThisRefMap = new Map();
71
72
  this.cid2ThisLocalMap = new Map();
72
73
  this.sdkMethodReturnValueMap = new Map();
74
+ // record the SDK API param, and create fake Values
75
+ this.sdkMethodParamValueMap = new Map();
76
+ this.fakeSdkMethodParamDeclaringStmt = new Stmt_1.ArkAssignStmt(new Local_1.Local(""), new Local_1.Local(""));
73
77
  this.funcHandledThisRound = new Set();
74
78
  this.updatedNodesThisRound = new Map();
75
79
  this.singletonFuncMap = new Map();
80
+ this.globalThisValue = new Local_1.Local(TSConst_1.GLOBAL_THIS);
76
81
  this.storagePropertyMap = new Map();
82
+ this.externalScopeVariableMap = new Map();
77
83
  this.pag = p;
78
84
  this.cg = cg;
79
85
  this.funcPags = new Map;
@@ -106,9 +112,11 @@ class PagBuilder {
106
112
  this.buildFuncPagAndAddToWorklist(csFuncID);
107
113
  });
108
114
  this.handleReachable();
115
+ this.globalThisPagNode = this.getOrNewGlobalThisNode(-1);
116
+ this.pag.addPagEdge(this.globalThisPagNode, this.globalThisPagNode, Pag_1.PagEdgeKind.Copy);
109
117
  }
110
118
  handleReachable() {
111
- if (this.worklist.length == 0) {
119
+ if (this.worklist.length === 0) {
112
120
  return false;
113
121
  }
114
122
  this.funcHandledThisRound.clear();
@@ -131,38 +139,45 @@ class PagBuilder {
131
139
  if (this.funcPags.has(funcID)) {
132
140
  return false;
133
141
  }
134
- let fpag = new Pag_1.FuncPag();
135
142
  let arkMethod = this.cg.getArkMethodByFuncID(funcID);
136
143
  if (arkMethod == null) {
137
- //throw new Error("function ID");
138
144
  return false;
139
145
  }
140
146
  let cfg = arkMethod.getCfg();
141
147
  if (!cfg) {
148
+ this.buildSDKFuncPag(funcID);
142
149
  return false;
143
150
  }
144
151
  logger.trace(`[build FuncPag] ${arkMethod.getSignature().toString()}`);
152
+ let fpag = new Pag_1.FuncPag();
145
153
  for (let stmt of cfg.getStmts()) {
146
154
  if (stmt instanceof Stmt_1.ArkAssignStmt) {
155
+ this.handleValueFromExternalScope(stmt.getRightOp(), funcID);
147
156
  // Add non-call edges
148
157
  let kind = this.getEdgeKindForAssignStmt(stmt);
149
- if (kind != Pag_1.PagEdgeKind.Unknown) {
158
+ if (kind !== Pag_1.PagEdgeKind.Unknown) {
150
159
  fpag.addInternalEdge(stmt, kind);
151
160
  continue;
152
161
  }
153
162
  // handle call
154
- let inkExpr = stmt.getInvokeExpr();
155
- if (inkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
163
+ let ivkExpr = stmt.getInvokeExpr();
164
+ if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
156
165
  let cs = this.cg.getCallSiteByStmt(stmt);
157
166
  if (cs) {
158
167
  // direct call is already existing in CG
168
+ // TODO: API Invoke stmt has anonymous method param, how to add these param into callee
159
169
  fpag.addNormalCallSite(cs);
170
+ if (ivkExpr.getMethodSignature().getDeclaringClassSignature()
171
+ .getDeclaringFileSignature().getFileName() === Const_1.UNKNOWN_FILE_NAME) {
172
+ fpag.addUnknownCallSite(cs);
173
+ continue;
174
+ }
160
175
  }
161
176
  else {
162
177
  throw new Error('Can not find static callsite');
163
178
  }
164
179
  }
165
- else if (inkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
180
+ else if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr || ivkExpr instanceof Expr_1.ArkPtrInvokeExpr) {
166
181
  let ptcs = this.cg.getDynCallsiteByStmt(stmt);
167
182
  if (ptcs) {
168
183
  this.addToDynamicCallSite(fpag, ptcs);
@@ -174,7 +189,14 @@ class PagBuilder {
174
189
  let cs = this.cg.getCallSiteByStmt(stmt);
175
190
  if (cs) {
176
191
  // direct call or constructor call is already existing in CG
177
- fpag.addNormalCallSite(cs);
192
+ // TODO: some ptr invoke stmt is recognized as Static invoke in tests/resources/callgraph/funPtrTest1/fnPtrTest4.ts
193
+ // TODO: instance invoke(ptr invoke)
194
+ if (this.cg.isUnknownMethod(cs.calleeFuncID)) {
195
+ fpag.addUnknownCallSite(cs);
196
+ }
197
+ else {
198
+ fpag.addNormalCallSite(cs);
199
+ }
178
200
  continue;
179
201
  }
180
202
  let dycs = this.cg.getDynCallsiteByStmt(stmt);
@@ -193,24 +215,51 @@ class PagBuilder {
193
215
  this.pagStat.numTotalFunction++;
194
216
  return true;
195
217
  }
218
+ /**
219
+ * will not create real funcPag, only create param values
220
+ */
221
+ buildSDKFuncPag(funcID) {
222
+ var _a;
223
+ // check if SDK method
224
+ let cgNode = this.cg.getNode(funcID);
225
+ if (!cgNode.isSdkMethod()) {
226
+ return;
227
+ }
228
+ let args = (_a = this.cg.getArkMethodByFuncID(funcID)) === null || _a === void 0 ? void 0 : _a.getParameters();
229
+ if (!args) {
230
+ return;
231
+ }
232
+ let paramArr = [];
233
+ args.forEach((arg) => {
234
+ let argInstance = new Local_1.Local(arg.getName(), arg.getType());
235
+ argInstance.setDeclaringStmt(this.fakeSdkMethodParamDeclaringStmt);
236
+ paramArr.push(argInstance);
237
+ });
238
+ this.sdkMethodParamValueMap.set(funcID, paramArr);
239
+ }
196
240
  buildPagFromFuncPag(funcID, cid) {
241
+ var _a;
197
242
  let funcPag = this.funcPags.get(funcID);
198
- if (funcPag == undefined) {
199
- //throw new Error("No Func PAG is found for #" + funcID);
243
+ if (funcPag === undefined) {
200
244
  return;
201
245
  }
202
246
  if (this.handledFunc.has(`${cid}-${funcID}`)) {
203
247
  return;
204
248
  }
205
249
  this.addEdgesFromFuncPag(funcPag, cid);
250
+ let interFuncPag = (_a = this.interFuncPags) === null || _a === void 0 ? void 0 : _a.get(funcID);
251
+ if (interFuncPag) {
252
+ this.addEdgesFromInterFuncPag(interFuncPag, cid);
253
+ }
206
254
  this.addCallsEdgesFromFuncPag(funcPag, cid);
207
- this.addDynamicCallSite(funcPag);
255
+ this.addDynamicCallSite(funcPag, funcID);
256
+ this.addUnknownCallSite(funcPag, funcID);
208
257
  this.handledFunc.add(`${cid}-${funcID}`);
209
258
  }
210
259
  /// Add Pag Nodes and Edges in function
211
260
  addEdgesFromFuncPag(funcPag, cid) {
212
261
  let inEdges = funcPag.getInternalEdges();
213
- if (inEdges == undefined) {
262
+ if (inEdges === undefined) {
214
263
  return false;
215
264
  }
216
265
  for (let e of inEdges) {
@@ -227,17 +276,17 @@ class PagBuilder {
227
276
  /// add Copy edges interprocedural
228
277
  addCallsEdgesFromFuncPag(funcPag, cid) {
229
278
  for (let cs of funcPag.getNormalCallSites()) {
279
+ let ivkExpr = cs.callStmt.getInvokeExpr();
230
280
  let calleeCid = this.ctx.getOrNewContext(cid, cs.calleeFuncID, true);
231
281
  let calleeCGNode = this.cg.getNode(cs.calleeFuncID);
232
- let ivkExpr = cs.callStmt.getInvokeExpr();
233
282
  // process the Storage API(Static)
234
283
  if (!this.processStorage(cs, calleeCGNode, cid)) {
235
284
  // If not Storage API, process normal edge
236
285
  this.addStaticPagCallEdge(cs, cid, calleeCid);
237
286
  }
238
287
  // Add edge to thisRef for special calls
239
- if (calleeCGNode.getKind() == CallGraph_1.CallGraphNodeKind.constructor ||
240
- calleeCGNode.getKind() == CallGraph_1.CallGraphNodeKind.intrinsic) {
288
+ if (calleeCGNode.getKind() === CallGraph_1.CallGraphNodeKind.constructor ||
289
+ calleeCGNode.getKind() === CallGraph_1.CallGraphNodeKind.intrinsic) {
241
290
  let callee = this.scene.getMethod(this.cg.getMethodByFuncID(cs.calleeFuncID));
242
291
  if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
243
292
  let baseNode = this.getOrNewPagNode(cid, ivkExpr.getBase());
@@ -285,13 +334,21 @@ class PagBuilder {
285
334
  return false;
286
335
  }
287
336
  processStorageSetOrCreate(cs, cid) {
288
- let propertyName = cs.args[0].getValue();
337
+ let propertyStr = this.getPropertyName(cs.args[0]);
338
+ if (!propertyStr) {
339
+ return;
340
+ }
341
+ let propertyName = propertyStr;
289
342
  let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
290
343
  let storageObj = cs.args[1];
291
344
  this.addPropertyLinkEdge(propertyNode, storageObj, cid, cs.callStmt, Pag_1.StorageLinkEdgeType.Local2Property);
292
345
  }
293
346
  processStorageLink(cs, cid) {
294
- let propertyName = cs.args[0].getValue();
347
+ let propertyStr = this.getPropertyName(cs.args[0]);
348
+ if (!propertyStr) {
349
+ return;
350
+ }
351
+ let propertyName = propertyStr;
295
352
  let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
296
353
  let leftOp = cs.callStmt.getLeftOp();
297
354
  let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
@@ -302,7 +359,11 @@ class PagBuilder {
302
359
  this.pag.addPagEdge(linkedOpNode, propertyNode, Pag_1.PagEdgeKind.Copy);
303
360
  }
304
361
  processStorageProp(cs, cid) {
305
- let propertyName = cs.args[0].getValue();
362
+ let propertyStr = this.getPropertyName(cs.args[0]);
363
+ if (!propertyStr) {
364
+ return;
365
+ }
366
+ let propertyName = propertyStr;
306
367
  let propertyNode = this.getOrNewPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
307
368
  let leftOp = cs.callStmt.getLeftOp();
308
369
  let linkedOpNode = this.pag.getOrNewNode(cid, leftOp);
@@ -312,19 +373,31 @@ class PagBuilder {
312
373
  this.pag.addPagEdge(propertyNode, linkedOpNode, Pag_1.PagEdgeKind.Copy);
313
374
  }
314
375
  processStorageSet(cs, cid) {
315
- let base = cs.callStmt.getInvokeExpr().getBase();
316
- let baseNode = this.pag.getOrNewNode(cid, base);
317
- if (baseNode.isStorageLinked()) {
318
- let argsNode = this.pag.getOrNewNode(cid, cs.args[0]);
319
- this.pag.addPagEdge(argsNode, baseNode, Pag_1.PagEdgeKind.Copy);
376
+ let ivkExpr = cs.callStmt.getInvokeExpr();
377
+ if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
378
+ let base = ivkExpr.getBase();
379
+ let baseNode = this.pag.getOrNewNode(cid, base);
380
+ if (baseNode.isStorageLinked()) {
381
+ let argsNode = this.pag.getOrNewNode(cid, cs.args[0]);
382
+ this.pag.addPagEdge(argsNode, baseNode, Pag_1.PagEdgeKind.Copy);
383
+ }
384
+ }
385
+ else if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
386
+ // TODO: process AppStorage.set()
320
387
  }
321
388
  }
322
389
  processStorageGet(cs, cid) {
390
+ if (!(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
391
+ return;
392
+ }
323
393
  let leftOp = cs.callStmt.getLeftOp();
324
394
  let ivkExpr = cs.callStmt.getInvokeExpr();
325
395
  let propertyName;
326
396
  if (ivkExpr instanceof Expr_1.ArkStaticInvokeExpr) {
327
- propertyName = cs.args[0].getValue();
397
+ let propertyStr = this.getPropertyName(cs.args[0]);
398
+ if (propertyStr) {
399
+ propertyName = propertyStr;
400
+ }
328
401
  }
329
402
  else if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
330
403
  let baseNode = this.pag.getOrNewNode(cid, ivkExpr.getBase());
@@ -332,19 +405,44 @@ class PagBuilder {
332
405
  propertyName = baseNode.getStorage().PropertyName;
333
406
  }
334
407
  }
335
- // TODO: should not new node
336
408
  let propertyNode = this.getPropertyNode(Pag_1.StorageType.APP_STORAGE, propertyName, cs.callStmt);
337
409
  if (!propertyNode) {
338
410
  return;
339
411
  }
340
412
  this.pag.addPagEdge(propertyNode, this.pag.getOrNewNode(cid, leftOp, cs.callStmt), Pag_1.PagEdgeKind.Copy, cs.callStmt);
341
413
  }
342
- addDynamicCallSite(funcPag) {
414
+ getPropertyName(value) {
415
+ if (value instanceof Local_1.Local) {
416
+ let type = value.getType();
417
+ if (type instanceof Type_1.StringType) {
418
+ return type.getName();
419
+ }
420
+ }
421
+ else if (value instanceof Constant_1.Constant) {
422
+ return value.getValue();
423
+ }
424
+ return undefined;
425
+ }
426
+ addDynamicCallSite(funcPag, funcID) {
343
427
  // add dyn callsite in funcpag to base node
344
428
  for (let cs of funcPag.getDynamicCallSites()) {
345
- let base = cs.callStmt.getInvokeExpr().getBase();
429
+ let invokeExpr = cs.callStmt.getInvokeExpr();
430
+ let base;
431
+ if (invokeExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
432
+ base = invokeExpr.getBase();
433
+ }
434
+ else if (invokeExpr instanceof Expr_1.ArkPtrInvokeExpr) {
435
+ base = invokeExpr.getFuncPtrLocal();
436
+ }
346
437
  // TODO: check base under different cid
347
438
  let baseNodeIDs = this.pag.getNodesByValue(base);
439
+ if (!baseNodeIDs) {
440
+ // bind the call site to export base
441
+ let interProceduralLocal = this.getSourceValueFromExternalScope(base, funcID);
442
+ if (interProceduralLocal) {
443
+ baseNodeIDs = this.pag.getNodesByValue(interProceduralLocal);
444
+ }
445
+ }
348
446
  if (!baseNodeIDs) {
349
447
  logger.warn(`[build dynamic call site] can not handle call site with base ${base.toString()}`);
350
448
  continue;
@@ -358,63 +456,114 @@ class PagBuilder {
358
456
  }
359
457
  }
360
458
  }
459
+ addUnknownCallSite(funcPag, funcID) {
460
+ var _a;
461
+ let method = this.cg.getArkMethodByFuncID(funcID);
462
+ if (!method) {
463
+ throw new Error(`can not find ArkMethod by FuncID ${funcID}`);
464
+ }
465
+ let locals = (_a = method.getBody()) === null || _a === void 0 ? void 0 : _a.getLocals();
466
+ funcPag.getUnknownCallSites().forEach((unknownCallSite) => {
467
+ var _a;
468
+ let calleeName = (_a = unknownCallSite.callStmt.getInvokeExpr()) === null || _a === void 0 ? void 0 : _a.getMethodSignature().getMethodSubSignature().getMethodName();
469
+ let base = locals.get(calleeName);
470
+ if (base) {
471
+ let baseNodeIDs = this.pag.getNodesByValue(base);
472
+ if (!baseNodeIDs) {
473
+ logger.warn(`[build dynamic call site] can not handle call site with base ${base.toString()}`);
474
+ return;
475
+ }
476
+ for (let nodeID of baseNodeIDs.values()) {
477
+ let node = this.pag.getNode(nodeID);
478
+ if (!(node instanceof Pag_1.PagLocalNode)) {
479
+ continue;
480
+ }
481
+ node.addRelatedUnknownCallSite(unknownCallSite);
482
+ }
483
+ }
484
+ });
485
+ }
361
486
  addDynamicCallEdge(cs, baseClassPTNode, cid) {
362
487
  let srcNodes = [];
363
488
  let ivkExpr = cs.callStmt.getInvokeExpr();
364
- let calleeName = ivkExpr.getMethodSignature().getMethodSubSignature().getMethodName();
365
489
  let ptNode = this.pag.getNode(baseClassPTNode);
366
490
  let value = ptNode.getValue();
367
- if (!(value instanceof Expr_1.ArkNewExpr || value instanceof Expr_1.ArkNewArrayExpr)) {
368
- return srcNodes;
369
- }
370
- let callee = null;
371
- if (value instanceof Expr_1.ArkNewExpr) {
372
- // get class signature
373
- let clsSig = value.getType().getClassSignature();
374
- let cls;
375
- cls = this.scene.getClass(clsSig);
376
- while (!callee && cls) {
377
- callee = cls.getMethodWithName(calleeName);
378
- cls = cls.getSuperClass();
379
- }
491
+ let callees = this.getDynamicCallee(ptNode, value, ivkExpr, cs);
492
+ for (let callee of callees) {
380
493
  if (!callee) {
381
- callee = this.scene.getMethod(ivkExpr.getMethodSignature());
494
+ continue;
382
495
  }
383
- }
384
- // anonymous method
385
- if (!callee) {
386
- // try to change callee to param anonymous method
387
- // TODO: anonymous method param and return value pointer pass
388
- let args = cs.args;
389
- if ((args === null || args === void 0 ? void 0 : args.length) == 1 && args[0].getType() instanceof Type_1.FunctionType) {
390
- callee = this.scene.getMethod(args[0].getType().getMethodSignature());
496
+ // get caller and callee CG node, add param and return value PAG edge
497
+ let dstCGNode = this.cg.getCallGraphNodeByMethod(callee.getSignature());
498
+ let callerNode = this.cg.getNode(cs.callerFuncID);
499
+ if (!callerNode) {
500
+ throw new Error("Can not get caller method node");
501
+ }
502
+ // update call graph
503
+ // TODO: movo to cgbuilder
504
+ this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt);
505
+ if (!this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
506
+ let calleeCid = this.ctx.getOrNewContext(cid, dstCGNode.getID(), true);
507
+ let staticCS = new CallGraph_1.CallSite(cs.callStmt, cs.args, dstCGNode.getID(), cs.callerFuncID);
508
+ let staticSrcNodes = this.addStaticPagCallEdge(staticCS, cid, calleeCid);
509
+ srcNodes.push(...staticSrcNodes);
510
+ // Pass base's pts to callee's this pointer
511
+ if (!dstCGNode.isSdkMethod() && ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
512
+ let srcBaseNode = this.addThisRefCallEdge(baseClassPTNode, cid, ivkExpr, callee, calleeCid, cs.callerFuncID);
513
+ srcNodes.push(srcBaseNode);
514
+ }
391
515
  }
392
516
  }
393
- if (!callee) {
394
- // while pts has {o_1, o_2} and invoke expr represents a method that only {o_1} has
395
- // return empty node when {o_2} come in
396
- return [];
517
+ return srcNodes;
518
+ }
519
+ getDynamicCallee(ptNode, value, ivkExpr, cs) {
520
+ let callee = [];
521
+ if (ptNode instanceof Pag_1.PagFuncNode) {
522
+ // function ptr invoke
523
+ let tempCallee = this.scene.getMethod(ptNode.getMethod());
524
+ if (!callee) {
525
+ return callee;
526
+ }
527
+ callee.push(tempCallee);
397
528
  }
398
- let dstCGNode = this.cg.getCallGraphNodeByMethod(callee.getSignature());
399
- let callerNode = this.cg.getNode(cs.callerFuncID);
400
- if (!callerNode) {
401
- throw new Error("Can not get caller method node");
402
- }
403
- // update call graph
404
- // TODO: movo to cgbuilder
405
- this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt);
406
- if (!this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
407
- let calleeCid = this.ctx.getOrNewContext(cid, dstCGNode.getID(), true);
408
- let staticCS = new CallGraph_1.CallSite(cs.callStmt, cs.args, dstCGNode.getID(), cs.callerFuncID);
409
- let staticSrcNodes = this.addStaticPagCallEdge(staticCS, cid, calleeCid);
410
- srcNodes.push(...staticSrcNodes);
411
- // Pass base's pts to callee's this pointer
412
- if (!dstCGNode.getIsSdkMethod()) {
413
- let srcBaseNode = this.addThisRefCallEdge(baseClassPTNode, cid, ivkExpr, callee, calleeCid, cs.callerFuncID);
414
- srcNodes.push(srcBaseNode);
529
+ else {
530
+ let calleeName = ivkExpr.getMethodSignature().getMethodSubSignature().getMethodName();
531
+ // instance method invoke
532
+ if (!(value instanceof Expr_1.ArkNewExpr || value instanceof Expr_1.ArkNewArrayExpr)) {
533
+ return callee;
534
+ }
535
+ let tempCallee;
536
+ // try to get callee by MethodSignature
537
+ if (value instanceof Expr_1.ArkNewExpr) {
538
+ // get class signature
539
+ let clsSig = value.getType().getClassSignature();
540
+ let cls;
541
+ cls = this.scene.getClass(clsSig);
542
+ while (!tempCallee && cls) {
543
+ tempCallee = cls.getMethodWithName(calleeName);
544
+ cls = cls.getSuperClass();
545
+ }
546
+ if (!tempCallee) {
547
+ tempCallee = this.scene.getMethod(ivkExpr.getMethodSignature());
548
+ }
549
+ }
550
+ if (!tempCallee && cs.args) {
551
+ // while pts has {o_1, o_2} and invoke expr represents a method that only {o_1} has
552
+ // return empty node when {o_2} come in
553
+ // try to get callee by anonymous method in param
554
+ for (let arg of cs.args) {
555
+ // TODO: anonymous method param and return value pointer pass
556
+ let argType = arg.getType();
557
+ if (argType instanceof Type_1.FunctionType) {
558
+ callee.push(this.scene.getMethod(argType.getMethodSignature()));
559
+ }
560
+ }
561
+ }
562
+ else if (tempCallee) {
563
+ callee.push(tempCallee);
415
564
  }
416
565
  }
417
- return srcNodes;
566
+ return callee;
418
567
  }
419
568
  addUpdatedNode(nodeID, diffPT) {
420
569
  var _a;
@@ -451,7 +600,7 @@ class PagBuilder {
451
600
  else {
452
601
  callees.push(callee);
453
602
  }
454
- if (callees.length == 0) {
603
+ if (callees.length === 0) {
455
604
  return srcNodes;
456
605
  }
457
606
  callees.forEach(callee => {
@@ -460,7 +609,7 @@ class PagBuilder {
460
609
  throw new Error("Can not get caller method node");
461
610
  }
462
611
  if (this.processStorage(cs, dstCGNode, cid)) {
463
- if (ivkExpr.getArgs().length != 0) {
612
+ if (ivkExpr.getArgs().length !== 0) {
464
613
  // for AppStorage.set() instance invoke, add obj to reanalyze list
465
614
  let argsNode = this.pag.getOrNewNode(cid, cs.args[0]);
466
615
  srcNodes.push(argsNode.getID());
@@ -489,26 +638,29 @@ class PagBuilder {
489
638
  const diffCallSites = new Set(Array.from(callSites).filter(item => !processedCallSites.has(item)));
490
639
  diffCallSites.forEach((cs) => {
491
640
  let ivkExpr = cs.callStmt.getInvokeExpr();
641
+ if (!(ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr)) {
642
+ return;
643
+ }
492
644
  // Get local of base class
493
645
  let base = ivkExpr.getBase();
494
646
  // TODO: remove this after multiple this local fixed
495
647
  base = this.getRealThisLocal(base, cs.callerFuncID);
496
648
  // Get PAG nodes for this base's local
497
649
  let ctx2NdMap = this.pag.getNodesByValue(base);
498
- if (ctx2NdMap) {
499
- for (let [cid] of ctx2NdMap.entries()) {
500
- reAnalyzeNodes.push(...this.handleUnkownDynamicCall(cs, cid));
501
- }
650
+ if (!ctx2NdMap) {
651
+ return;
652
+ }
653
+ for (let [cid] of ctx2NdMap.entries()) {
654
+ reAnalyzeNodes.push(...this.handleUnkownDynamicCall(cs, cid));
502
655
  }
503
656
  });
504
657
  }
505
658
  return reAnalyzeNodes;
506
659
  }
507
660
  addThisRefCallEdge(baseClassPTNode, cid, ivkExpr, callee, calleeCid, callerFunID) {
508
- //let thisPtr = callee.getThisInstance();
509
661
  var _a;
510
662
  if (!callee || !callee.getCfg()) {
511
- console.log("callee is null");
663
+ logger.error(`callee is null`);
512
664
  return -1;
513
665
  }
514
666
  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);
@@ -523,6 +675,14 @@ class PagBuilder {
523
675
  let srcBaseLocal = ivkExpr.getBase();
524
676
  srcBaseLocal = this.getRealThisLocal(srcBaseLocal, callerFunID);
525
677
  let srcNodeId = this.pag.hasCtxNode(cid, srcBaseLocal);
678
+ if (!srcNodeId) {
679
+ // this check is for export local and closure use
680
+ // replace the invoke base, because its origin base has no pag node
681
+ let interProceduralLocal = this.getSourceValueFromExternalScope(srcBaseLocal, callerFunID);
682
+ if (interProceduralLocal) {
683
+ srcNodeId = this.pag.hasCtxNode(cid, interProceduralLocal);
684
+ }
685
+ }
526
686
  if (!srcNodeId) {
527
687
  throw new Error('Can not get base node');
528
688
  }
@@ -545,35 +705,10 @@ class PagBuilder {
545
705
  let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
546
706
  if (!calleeMethod) {
547
707
  // TODO: check if nodes need to delete
548
- // this.cg.removeCallGraphNode(cs.calleeFuncID)
549
708
  return srcNodes;
550
709
  }
551
- if (calleeNode.getIsSdkMethod()) {
552
- let returnType = calleeMethod.getReturnType();
553
- // TODO: add new array type
554
- if (!(returnType instanceof Type_1.ClassType) || !(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
555
- return srcNodes;
556
- }
557
- // check fake heap object exists or not
558
- let cidMap = this.sdkMethodReturnValueMap.get(calleeMethod);
559
- if (!cidMap) {
560
- cidMap = new Map();
561
- }
562
- let newExpr = cidMap.get(calleeCid);
563
- if (!newExpr) {
564
- if (returnType instanceof Type_1.ClassType) {
565
- newExpr = new Expr_1.ArkNewExpr(returnType);
566
- }
567
- // } else if (returnType instanceof ArrayType) {
568
- // TODO: check how to transform array type 2 newArrayExpr
569
- // newExpr = new ArkNewArrayExpr(returnType.getBaseType(), )
570
- // }
571
- }
572
- cidMap.set(calleeCid, newExpr);
573
- this.sdkMethodReturnValueMap.set(calleeMethod, cidMap);
574
- let srcPagNode = this.getOrNewPagNode(calleeCid, newExpr);
575
- let dstPagNode = this.getOrNewPagNode(callerCid, cs.callStmt.getLeftOp(), cs.callStmt);
576
- this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Address, cs.callStmt);
710
+ if (calleeNode.isSdkMethod()) {
711
+ srcNodes.push(...this.addSDKMethodPagCallEdge(cs, callerCid, calleeCid));
577
712
  return srcNodes;
578
713
  }
579
714
  if (!calleeMethod.getCfg()) {
@@ -584,7 +719,6 @@ class PagBuilder {
584
719
  // callee cid will updated if callee is singleton
585
720
  calleeCid = calleeCS.cid;
586
721
  // TODO: getParameterInstances's performance is not good. Need to refactor
587
- //let params = calleeMethod.getParameterInstances();
588
722
  let params = calleeMethod.getCfg().getStmts()
589
723
  .filter(stmt => stmt instanceof Stmt_1.ArkAssignStmt && stmt.getRightOp() instanceof Ref_1.ArkParameterRef)
590
724
  .map(stmt => stmt.getRightOp());
@@ -595,7 +729,6 @@ class PagBuilder {
595
729
  let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b.at(i);
596
730
  let param = params.at(i);
597
731
  // TODO: param type should be ArkParameterRef?
598
- //if (arg && param && param instanceof ArkParameterRef) {
599
732
  if (arg && param) {
600
733
  if (arg instanceof Constant_1.Constant) {
601
734
  continue;
@@ -629,7 +762,7 @@ class PagBuilder {
629
762
  continue;
630
763
  }
631
764
  else if (retValue instanceof Expr_1.AbstractExpr) {
632
- console.log(retValue);
765
+ logger.debug(retValue);
633
766
  continue;
634
767
  }
635
768
  else {
@@ -639,6 +772,86 @@ class PagBuilder {
639
772
  }
640
773
  return srcNodes;
641
774
  }
775
+ addSDKMethodPagCallEdge(cs, callerCid, calleeCid) {
776
+ let srcNodes = [];
777
+ let calleeNode = this.cg.getNode(cs.calleeFuncID);
778
+ let calleeMethod = this.scene.getMethod(calleeNode.getMethod());
779
+ if (!calleeMethod) {
780
+ return srcNodes;
781
+ }
782
+ if (!this.sdkMethodParamValueMap.has(calleeNode.getID())) {
783
+ this.buildSDKFuncPag(calleeNode.getID());
784
+ }
785
+ this.addSDKMethodReturnPagEdge(cs, callerCid, calleeCid, calleeMethod);
786
+ srcNodes.push(...this.addSDKMethodParamPagEdge(cs, callerCid, calleeCid, calleeNode.getID()));
787
+ return srcNodes;
788
+ }
789
+ addSDKMethodReturnPagEdge(cs, callerCid, calleeCid, calleeMethod) {
790
+ let returnType = calleeMethod.getReturnType();
791
+ if (!(returnType instanceof Type_1.ClassType) || !(cs.callStmt instanceof Stmt_1.ArkAssignStmt)) {
792
+ return;
793
+ }
794
+ // check fake heap object exists or not
795
+ let cidMap = this.sdkMethodReturnValueMap.get(calleeMethod);
796
+ if (!cidMap) {
797
+ cidMap = new Map();
798
+ }
799
+ let newExpr = cidMap.get(calleeCid);
800
+ if (!newExpr) {
801
+ if (returnType instanceof Type_1.ClassType) {
802
+ newExpr = new Expr_1.ArkNewExpr(returnType);
803
+ }
804
+ }
805
+ cidMap.set(calleeCid, newExpr);
806
+ this.sdkMethodReturnValueMap.set(calleeMethod, cidMap);
807
+ let srcPagNode = this.getOrNewPagNode(calleeCid, newExpr);
808
+ let dstPagNode = this.getOrNewPagNode(callerCid, cs.callStmt.getLeftOp(), cs.callStmt);
809
+ this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Address, cs.callStmt);
810
+ }
811
+ addSDKMethodParamPagEdge(cs, callerCid, calleeCid, funcID) {
812
+ var _a, _b;
813
+ let argNum = (_a = cs.args) === null || _a === void 0 ? void 0 : _a.length;
814
+ let srcNodes = [];
815
+ if (argNum) {
816
+ // add args to parameters edges
817
+ for (let i = 0; i < argNum; i++) {
818
+ let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b.at(i);
819
+ let paramValue;
820
+ if (arg instanceof Local_1.Local && arg.getType() instanceof Type_1.FunctionType) {
821
+ // TODO: cannot find value
822
+ paramValue = this.sdkMethodParamValueMap.get(funcID)[i];
823
+ }
824
+ else {
825
+ continue;
826
+ }
827
+ if (arg && paramValue) {
828
+ // Get or create new PAG node for argument and parameter
829
+ let srcPagNode = this.getOrNewPagNode(callerCid, arg, cs.callStmt);
830
+ let dstPagNode = this.getOrNewPagNode(calleeCid, paramValue, cs.callStmt);
831
+ if (dstPagNode instanceof Pag_1.PagLocalNode) {
832
+ // set the fake param Value in PagLocalNode
833
+ /**
834
+ * TODO: !!!
835
+ * some API param is in the form of anonymous method:
836
+ * component/common.d.ts
837
+ * declare function animateTo(value: AnimateParam, event: () => void): void;
838
+ *
839
+ * this param fake Value will create PagFuncNode rather than PagLocalNode
840
+ * when this API is called, the anonymous method pointer will not be able to pass into the fake Value PagNode
841
+ */
842
+ dstPagNode.setSdkParam();
843
+ let sdkParamInvokeStmt = new Stmt_1.ArkInvokeStmt(new Expr_1.ArkPtrInvokeExpr(arg.getType().getMethodSignature(), paramValue, []));
844
+ // create new DynCallSite
845
+ let sdkParamCallSite = new CallGraph_1.DynCallSite(funcID, sdkParamInvokeStmt, undefined, undefined);
846
+ dstPagNode.addRelatedDynCallSite(sdkParamCallSite);
847
+ }
848
+ this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
849
+ srcNodes.push(srcPagNode.getID());
850
+ }
851
+ }
852
+ }
853
+ return srcNodes;
854
+ }
642
855
  getOrNewPagNode(cid, v, s) {
643
856
  if (v instanceof Ref_1.ArkThisRef) {
644
857
  return this.getOrNewThisRefNode(cid, v);
@@ -647,15 +860,17 @@ class PagBuilder {
647
860
  // remove below block once this issue fixed
648
861
  // globalThis process can not be removed while all `globalThis` ref is the same Value
649
862
  if (v instanceof Local_1.Local) {
650
- if (v.getName() == "this") {
863
+ if (v.getName() === "this") {
651
864
  return this.getOrNewThisLoalNode(cid, v, s);
652
865
  }
653
- else if (v.getName() == Pag_1.GLOBAL_THIS && v.getDeclaringStmt() == null) {
866
+ else if (v.getName() === TSConst_1.GLOBAL_THIS && v.getDeclaringStmt() == null) {
654
867
  // globalThis node has no cid
655
- return this.getOrNewGlobalThisNode(0);
868
+ return this.getOrNewGlobalThisNode(-1);
656
869
  }
657
870
  }
658
- v = this.getRealInstanceRef(v);
871
+ if (v instanceof Ref_1.ArkInstanceFieldRef || v instanceof Ref_1.ArkStaticFieldRef) {
872
+ v = this.getRealInstanceRef(v);
873
+ }
659
874
  return this.pag.getOrNewNode(cid, v, s);
660
875
  }
661
876
  /**
@@ -706,7 +921,7 @@ class PagBuilder {
706
921
  }
707
922
  getPropertyNode(storage, propertyName, stmt) {
708
923
  let storageMap = this.storagePropertyMap.get(storage);
709
- let propertyLocal = undefined;
924
+ let propertyLocal;
710
925
  if (!storageMap) {
711
926
  storageMap = new Map();
712
927
  this.storagePropertyMap.set(storage, storageMap);
@@ -764,7 +979,7 @@ class PagBuilder {
764
979
  let real;
765
980
  if (v instanceof Ref_1.ArkInstanceFieldRef) {
766
981
  base = v.getBase();
767
- if (base instanceof Local_1.Local && base.getName() == Pag_1.GLOBAL_THIS && base.getDeclaringStmt() == null) {
982
+ if (base instanceof Local_1.Local && base.getName() === TSConst_1.GLOBAL_THIS && base.getDeclaringStmt() == null) {
768
983
  // replace the base in fieldRef
769
984
  base = this.getGlobalThisValue();
770
985
  v.setBase(base);
@@ -797,13 +1012,13 @@ class PagBuilder {
797
1012
  this.singletonFuncMap.set(funcID, false);
798
1013
  return false;
799
1014
  }
800
- if (!arkMethod.getModifiers().has(TSConst_1.STATIC_KEYWORD)) {
1015
+ if (!arkMethod.isStatic()) {
801
1016
  this.singletonFuncMap.set(funcID, false);
802
1017
  return false;
803
1018
  }
804
1019
  let funcPag = this.funcPags.get(funcID);
805
1020
  let heapObjects = [...funcPag.getInternalEdges()]
806
- .filter(edge => edge.kind == Pag_1.PagEdgeKind.Address)
1021
+ .filter(edge => edge.kind === Pag_1.PagEdgeKind.Address)
807
1022
  .map(edge => edge.dst);
808
1023
  let returnValues = arkMethod.getReturnValues();
809
1024
  let result = this.isValueConnected([...funcPag.getInternalEdges()], heapObjects, returnValues);
@@ -868,8 +1083,7 @@ class PagBuilder {
868
1083
  return false;
869
1084
  }
870
1085
  getGlobalThisValue() {
871
- var _a;
872
- return (_a = this.globalThisValue) !== null && _a !== void 0 ? _a : new Local_1.Local(Pag_1.GLOBAL_THIS);
1086
+ return this.globalThisValue;
873
1087
  }
874
1088
  getEdgeKindForAssignStmt(stmt) {
875
1089
  if (this.stmtIsCreateAddressObj(stmt)) {
@@ -902,13 +1116,15 @@ class PagBuilder {
902
1116
  switch (storageName) {
903
1117
  case 'AppStorage':
904
1118
  return Pag_1.StorageType.APP_STORAGE;
905
- case 'SubscribedAbstractProperty':
1119
+ case 'SubscribedAbstractProperty': {
906
1120
  let calleeBaseLocal = cs.callStmt.getInvokeExpr().getBase();
907
1121
  let calleeBaseLocalNode = this.pag.getOrNewNode(cid, calleeBaseLocal);
908
1122
  if (calleeBaseLocalNode.isStorageLinked()) {
909
1123
  let storage = calleeBaseLocalNode.getStorage();
910
1124
  return storage.StorageType;
911
1125
  }
1126
+ return Pag_1.StorageType.Undefined;
1127
+ }
912
1128
  default:
913
1129
  return Pag_1.StorageType.Undefined;
914
1130
  }
@@ -920,10 +1136,10 @@ class PagBuilder {
920
1136
  let lhOp = stmt.getLeftOp();
921
1137
  let rhOp = stmt.getRightOp();
922
1138
  if ((rhOp instanceof Expr_1.ArkNewExpr || rhOp instanceof Expr_1.ArkNewArrayExpr) ||
923
- (lhOp instanceof Local_1.Local && rhOp instanceof Local_1.Local &&
924
- rhOp.getType() instanceof Type_1.FunctionType &&
925
- rhOp.getDeclaringStmt() === null ||
926
- (rhOp instanceof Local_1.Local && rhOp.getName() == Pag_1.GLOBAL_THIS && rhOp.getDeclaringStmt() == null))) {
1139
+ (lhOp instanceof Local_1.Local && ((rhOp instanceof Local_1.Local && rhOp.getType() instanceof Type_1.FunctionType &&
1140
+ rhOp.getDeclaringStmt() === null) ||
1141
+ (rhOp instanceof Ref_1.AbstractFieldRef && rhOp.getType() instanceof Type_1.FunctionType))) ||
1142
+ (rhOp instanceof Local_1.Local && rhOp.getName() === TSConst_1.GLOBAL_THIS && rhOp.getDeclaringStmt() == null)) {
927
1143
  return true;
928
1144
  }
929
1145
  // TODO: add other Address Obj creation
@@ -973,7 +1189,7 @@ class PagBuilder {
973
1189
  }
974
1190
  getRealThisLocal(input, funcId) {
975
1191
  var _a;
976
- if (input.getName() != 'this')
1192
+ if (input.getName() !== 'this')
977
1193
  return input;
978
1194
  let real = input;
979
1195
  let f = this.cg.getArkMethodByFuncID(funcId);
@@ -1003,5 +1219,142 @@ class PagBuilder {
1003
1219
  getHandledFuncs() {
1004
1220
  return Array.from(this.funcPags.keys());
1005
1221
  }
1222
+ /**
1223
+ * build export edge in internal func pag
1224
+ * @param value: Value that need to check if it is from import/export
1225
+ * @param originValue: if Value if InstanceFieldRef, the base will be passed to `value` recursively,
1226
+ * fieldRef will be passed to `originValue`
1227
+ */
1228
+ handleValueFromExternalScope(value, funcID, originValue) {
1229
+ if (value instanceof Local_1.Local) {
1230
+ if (value.getDeclaringStmt()) {
1231
+ // not from external scope
1232
+ return;
1233
+ }
1234
+ if (!value.getType()) {
1235
+ return;
1236
+ }
1237
+ let srcLocal = this.getSourceValueFromExternalScope(value, funcID);
1238
+ if (srcLocal) {
1239
+ // if `value` is from field base, use origin value(fieldRef) instead
1240
+ this.addInterFuncEdge(srcLocal, originValue !== null && originValue !== void 0 ? originValue : value, funcID);
1241
+ }
1242
+ }
1243
+ else if (value instanceof Ref_1.ArkInstanceFieldRef) {
1244
+ let base = value.getBase();
1245
+ if (base) {
1246
+ this.handleValueFromExternalScope(base, funcID, value);
1247
+ }
1248
+ }
1249
+ }
1250
+ addInterFuncEdge(src, dst, funcID) {
1251
+ var _a, _b, _c;
1252
+ this.interFuncPags = (_a = this.interFuncPags) !== null && _a !== void 0 ? _a : new Map();
1253
+ let interFuncPag = (_b = this.interFuncPags.get(funcID)) !== null && _b !== void 0 ? _b : new Pag_1.InterFuncPag();
1254
+ // Export a local
1255
+ // Add a InterProcedural edge
1256
+ if (dst instanceof Local_1.Local) {
1257
+ let e = { src: src, dst: dst, kind: Pag_1.PagEdgeKind.InterProceduralCopy };
1258
+ interFuncPag.addToInterProceduralEdgeSet(e);
1259
+ this.addExportVariableMap(src, dst);
1260
+ }
1261
+ else if (dst instanceof Ref_1.ArkInstanceFieldRef) {
1262
+ // record the export base use
1263
+ this.addExportVariableMap(src, dst.getBase());
1264
+ }
1265
+ this.interFuncPags.set(funcID, interFuncPag);
1266
+ // Put the function which the src belongs to to worklist
1267
+ let srcFunc = (_c = src.getDeclaringStmt()) === null || _c === void 0 ? void 0 : _c.getCfg().getDeclaringMethod();
1268
+ if (srcFunc) {
1269
+ let srcFuncID = this.cg.getCallGraphNodeByMethod(srcFunc.getSignature()).getID();
1270
+ let cid = this.ctx.getNewContextID(srcFuncID);
1271
+ let csFuncID = new CSFuncID(cid, srcFuncID);
1272
+ this.buildFuncPagAndAddToWorklist(csFuncID);
1273
+ }
1274
+ // Extend other types of src here
1275
+ }
1276
+ getSourceValueFromExternalScope(value, funcID) {
1277
+ let sourceValue;
1278
+ // TODO: first from default method
1279
+ sourceValue = this.getDefaultMethodSourceValue(value, funcID);
1280
+ if (!sourceValue) {
1281
+ sourceValue = this.getExportSourceValue(value, funcID);
1282
+ }
1283
+ return sourceValue;
1284
+ }
1285
+ getDefaultMethodSourceValue(value, funcID) {
1286
+ var _a, _b, _c, _d, _e, _f, _g;
1287
+ // namespace check
1288
+ let arkMethod = this.cg.getArkMethodByFuncID(funcID);
1289
+ if (!arkMethod) {
1290
+ return;
1291
+ }
1292
+ let declaringNameSpace = arkMethod.getDeclaringArkClass().getDeclaringArkNamespace();
1293
+ while (declaringNameSpace) {
1294
+ let nameSpaceLocals = (_c = (_b = (_a = declaringNameSpace.getDefaultClass()
1295
+ .getDefaultArkMethod()) === null || _a === void 0 ? void 0 : _a.getBody()) === null || _b === void 0 ? void 0 : _b.getLocals()) !== null && _c !== void 0 ? _c : new Map();
1296
+ if (nameSpaceLocals.has(value.getName())) {
1297
+ return nameSpaceLocals.get(value.getName());
1298
+ }
1299
+ declaringNameSpace = (_d = declaringNameSpace.getDeclaringArkNamespace()) !== null && _d !== void 0 ? _d : undefined;
1300
+ }
1301
+ // file check
1302
+ let declaringFile = arkMethod.getDeclaringArkFile();
1303
+ let fileLocals = (_g = (_f = (_e = declaringFile.getDefaultClass()
1304
+ .getDefaultArkMethod()) === null || _e === void 0 ? void 0 : _e.getBody()) === null || _f === void 0 ? void 0 : _f.getLocals()) !== null && _g !== void 0 ? _g : new Map();
1305
+ if (!fileLocals.has(value.getName())) {
1306
+ return;
1307
+ }
1308
+ return fileLocals.get(value.getName());
1309
+ }
1310
+ getExportSourceValue(value, funcID) {
1311
+ let curMethod = this.cg.getArkMethodByFuncID(funcID);
1312
+ if (!curMethod) {
1313
+ return;
1314
+ }
1315
+ let curFile = curMethod.getDeclaringArkFile();
1316
+ let impInfo = curFile.getImportInfoBy(value.getName());
1317
+ if (!impInfo) {
1318
+ return;
1319
+ }
1320
+ let exportSource = impInfo.getLazyExportInfo();
1321
+ if (!exportSource) {
1322
+ return;
1323
+ }
1324
+ let exportSouceValue = exportSource.getArkExport();
1325
+ if (exportSouceValue instanceof Local_1.Local) {
1326
+ return exportSouceValue;
1327
+ }
1328
+ }
1329
+ addExportVariableMap(src, dst) {
1330
+ var _a;
1331
+ let exportMap = (_a = this.externalScopeVariableMap.get(src)) !== null && _a !== void 0 ? _a : [];
1332
+ if (!exportMap.includes(dst)) {
1333
+ exportMap.push(dst);
1334
+ this.externalScopeVariableMap.set(src, exportMap);
1335
+ }
1336
+ }
1337
+ getExportVariableMap(src) {
1338
+ var _a;
1339
+ return (_a = this.externalScopeVariableMap.get(src)) !== null && _a !== void 0 ? _a : [];
1340
+ }
1341
+ /// Add inter-procedural Pag Nodes and Edges
1342
+ addEdgesFromInterFuncPag(interFuncPag, cid) {
1343
+ let edges = interFuncPag.getInterProceduralEdges();
1344
+ if (edges.size === 0) {
1345
+ return false;
1346
+ }
1347
+ for (let e of edges) {
1348
+ // Existing local exported nodes -> ExportNode
1349
+ let exportLocal = e.src;
1350
+ let dstPagNode = this.getOrNewPagNode(cid, e.dst);
1351
+ // get export local node in all cid
1352
+ let existingNodes = this.pag.getNodesByValue(exportLocal);
1353
+ existingNodes === null || existingNodes === void 0 ? void 0 : existingNodes.forEach(n => {
1354
+ this.pag.addPagEdge(this.pag.getNode(n), dstPagNode, e.kind);
1355
+ });
1356
+ }
1357
+ return true;
1358
+ }
1006
1359
  }
1007
1360
  exports.PagBuilder = PagBuilder;