/package/src/progpilot/Outputs/MyOutputs.php

https://github.com/designsecurity/progpilot · PHP · 228 lines · 177 code · 44 blank · 7 comment · 12 complexity · e4634381ac88d5144b8d45ffca44cccf MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of ProgPilot, a static analyzer for security
  4. *
  5. * @copyright 2017 Eric Therond. All rights reserved
  6. * @license MIT See LICENSE at the root of the project for more info
  7. */
  8. namespace progpilot\Outputs;
  9. use progpilot\Lang;
  10. use progpilot\Representations\Callgraph;
  11. use progpilot\Representations\ControlFlowGraph;
  12. use progpilot\Representations\AbstractSyntaxTree;
  13. use PhpParser\NodeTraverser;
  14. class MyOutputs
  15. {
  16. private $results;
  17. private $resolveIncludes;
  18. private $resolveIncludesFile;
  19. private $onAddResult;
  20. private $taintedFlow;
  21. private $countfilesanalyzed;
  22. public $currentIncludesFile;
  23. public $cfg;
  24. public $callgraph;
  25. public $ast;
  26. public function __construct()
  27. {
  28. $this->resolveIncludes = false;
  29. $this->resolveIncludesFile = null;
  30. $this->currentIncludesFile = [];
  31. $this->results = [];
  32. $this->taintedFlow = false;
  33. $this->onAddResult = null;
  34. $this->countfilesanalyzed = 0;
  35. $this->resetRepresentations();
  36. }
  37. public function resetRepresentations()
  38. {
  39. //$this->results = [];
  40. $this->cfg = new ControlFlowGraph;
  41. $this->callgraph = new Callgraph;
  42. $this->ast = new AbstractSyntaxTree;
  43. }
  44. public function getAst()
  45. {
  46. $nodesjson = [];
  47. $linksjson = [];
  48. foreach ($this->ast->getNodes() as $node) {
  49. $hash = spl_object_hash($node);
  50. $nodesjson[] = array('name' => get_class($node), 'id' => $hash);
  51. }
  52. foreach ($this->ast->getEdges() as $edge) {
  53. $caller = $edge[0];
  54. $callee = $edge[1];
  55. $hashcaller = spl_object_hash($caller);
  56. $hashcallee = spl_object_hash($callee);
  57. if ($hashcaller !== $hashcallee) {
  58. $linksjson[] = array('target' => $hashcallee, 'source' => $hashcaller);
  59. }
  60. }
  61. $outputjson = array('nodes' => $nodesjson, 'links' => $linksjson);
  62. return $outputjson;
  63. }
  64. public function getCfg()
  65. {
  66. $nodesjson = [];
  67. $linksjson = [];
  68. $realNodes = [];
  69. foreach ($this->cfg->getNodes() as $id => $node) {
  70. $realNodes[] = $id;
  71. $nodesjson[] = array('name' => $this->cfg->getTextOfMyBlock($id), 'id' => $id);
  72. }
  73. foreach ($this->cfg->getEdges() as $edge) {
  74. $callerId = $this->cfg->getIdOfNode($edge[0]);
  75. $calleeId = $this->cfg->getIdOfNode($edge[1]);
  76. if ($callerId !== $calleeId
  77. && in_array($callerId, $realNodes, true)
  78. && in_array($calleeId, $realNodes, true)) {
  79. $linksjson[] = array('source' => $callerId, 'target' => $calleeId);
  80. }
  81. }
  82. $outputjson = array('nodes' => $nodesjson, 'links' => $linksjson);
  83. return $outputjson;
  84. }
  85. public function getCallGraph()
  86. {
  87. $nodesjson = [];
  88. $linksjson = [];
  89. $realNodes = [];
  90. $nodes = $this->callgraph->getNodes();
  91. foreach ($nodes as $nodeCaller) {
  92. $realNodes[] = $nodeCaller->getId();
  93. $nodesjson[] = array('name' => $nodeCaller->getName(), 'id' => $nodeCaller->getId());
  94. }
  95. foreach ($nodes as $key => $nodeCaller) {
  96. foreach ($nodeCaller->getChildren() as $key => $nodeCalleeId) {
  97. $nodeCallee = $nodes[$nodeCalleeId];
  98. if ($nodeCaller->getId() !== $nodeCallee->getId()
  99. && in_array($nodeCaller->getId(), $realNodes, true)
  100. && in_array($nodeCallee->getId(), $realNodes, true)) {
  101. $linksjson[] = array('source' => $nodeCaller->getId(), 'target' => $nodeCallee->getId());
  102. }
  103. }
  104. }
  105. $outputjson = array('nodes' => $nodesjson, 'links' => $linksjson);
  106. return $outputjson;
  107. }
  108. public function setOnAddResult($func)
  109. {
  110. $this->onAddResult = $func;
  111. }
  112. public function getOnAddResult()
  113. {
  114. return $this->onAddResult;
  115. }
  116. public function addResult($temp)
  117. {
  118. if (!in_array($temp, $this->results, true)) {
  119. if (!is_null($this->onAddResult)) {
  120. $params = array($temp);
  121. call_user_func($this->onAddResult, $params);
  122. }
  123. $this->results[] = $temp;
  124. }
  125. }
  126. public function setResults(&$results)
  127. {
  128. $this->results = &$results;
  129. }
  130. public function &getResults()
  131. {
  132. return $this->results;
  133. }
  134. public function getCountAnalyzedFiles()
  135. {
  136. return $this->countfilesanalyzed;
  137. }
  138. public function setCountAnalyzedFiles($nb)
  139. {
  140. $this->countfilesanalyzed = $nb;
  141. }
  142. public function getResolveIncludes()
  143. {
  144. return $this->resolveIncludes;
  145. }
  146. public function resolveIncludes($option)
  147. {
  148. $this->resolveIncludes = $option;
  149. }
  150. public function resolveIncludesFile($file)
  151. {
  152. $this->resolveIncludesFile = $file;
  153. }
  154. public function getresolveIncludesFile()
  155. {
  156. return $this->resolveIncludesFile;
  157. }
  158. public function taintedFlow($bool)
  159. {
  160. $this->taintedFlow = $bool;
  161. }
  162. public function getTaintedFlow()
  163. {
  164. return $this->taintedFlow;
  165. }
  166. public function writeIncludesFile()
  167. {
  168. if ($this->resolveIncludes) {
  169. $fp = fopen($this->resolveIncludesFile, "w");
  170. if ($fp) {
  171. $myArray = "";
  172. if (count($this->currentIncludesFile) > 0) {
  173. $myArray = [];
  174. foreach ($this->currentIncludesFile as $includeFile) {
  175. $myArray[] = [$includeFile->getName(), $includeFile->getLine(), $includeFile->getColumn()];
  176. }
  177. }
  178. $outputjson = array('includes_not_resolved' => $myArray);
  179. fwrite($fp, json_encode($outputjson, JSON_UNESCAPED_SLASHES));
  180. fclose($fp);
  181. }
  182. }
  183. }
  184. }