/** * sink多块回溯 * @param string $argName * @param BasicBlock $block * @param flowNum 遍历过的flow数量 * @return array */ public function sinkMultiBlockTraceback($argName, $block, $flowsNum = 0) { $mulitBlockHandlerUtils = new multiBlockHandlerUtils($block); $blockList = $mulitBlockHandlerUtils->getPathArr(); $flows = $block->getBlockSummary()->getDataFlowMap(); //当前块flows没有遍历完 if (count($flows) != $flowsNum) { return $this->sinkTracebackBlock($argName, $block, $flowsNum); } if ($blockList == null || count($blockList) == 0) { return array($argName); } if (!is_array($blockList[0])) { //如果不是平行结构 $flows = $block->getBlockSummary()->getDataFlowMap(); if (count($flows) == $flowsNum) { $block = $blockList[0]; $ret = $this->sinkTracebackBlock($argName, $block, 0); return $ret; } $ret = $this->sinkTracebackBlock($argName, $block, 0); return $ret; } else { //平行结构 //当遇到sink函数时回溯碰到平行结构,那么遍历平行结构,将所有危险的相关变量全部记录下来 $retarr = array(); foreach ($blockList[0] as $block) { $ret = array(); $ret = $this->sinkTracebackBlock($argName, $block, 0); $retarr = array_merge($retarr, $ret); } return $retarr; } }
/** * return变量多块回溯 * @param 变量对象 $arg * @param 当前块 $block * @param 数据流已处理数量 $flowsNum * @return void|净化信息 */ public function sanitiMultiBlockHandler($arg, $block, $flowsNum = 0) { $mulitBlockHandlerUtils = new multiBlockHandlerUtils($block); $blockList = $mulitBlockHandlerUtils->getPathArr(); $flows = $block->getBlockSummary()->getDataFlowMap(); //当前块flows没有遍历完 if (count($flows) != $flowsNum) { return $this->sanitiTracebackBlock($arg, $block, $flowsNum); } else { $flowsNum = 0; } if ($blockList == null || count($blockList) == 0) { return; } if (!is_array($blockList[0])) { //如果不是平行结构 $flows = $block->getBlockSummary()->getDataFlowMap(); if (!$flowsNum) { $block = $blockList[0]; $ret = $this->sanitiTracebackBlock($arg, $block, 0); return $ret; } $ret = $this->sanitiTracebackBlock($arg, $block, $flowsNum); return $ret; } else { //平行结构 //分别遍历每一个平行基本块及其以上,对得到的净化信息,合并共有的,返回 global $SECURES_TYPE_ALL; $retarr = $SECURES_TYPE_ALL; $isFind = false; foreach ($blockList[0] as $block) { $flows = $block->getBlockSummary()->getDataFlowMap(); if (!$flowsNum) { $ret = null; $ret = $this->sanitiTracebackBlock($arg, $block, 0); if ($ret[0]) { $retarr = array_intersect($ret, $retarr); $isFind = true; } } else { $ret = $this->sanitiTracebackBlock($arg, $block, $flowsNum); if ($ret[0]) { $retarr = array_intersect($ret['type'], $retarr); $isFind = true; } } } if ($isFind) { return array(true, 'type' => $retarr); } else { return array(false); } } }
/** * 相同净化变量的多块回溯 * @param 变量名 $varName * @param 当前块 $block * @param 数据流 $dataFlows * @return */ public static function encodeSameVarMultiBlockHandler($varName, $block, $dataFlows) { //print_r("enter sanitiSameVarMultiBlock<br/>"); $mulitBlockHandlerUtils = new multiBlockHandlerUtils($block); $blockList = $mulitBlockHandlerUtils->getPathArr(); //当前块flows没有遍历完 if (count($dataFlows) != 0) { return self::encodeSameVarTraceback($varName, $block, $dataFlows); } if ($blockList == null || count($blockList) == 0) { return array(false); } if (!is_array($blockList[0])) { //如果不是平行结构 if (count($dataFlows) == 0) { //当前块回溯完毕,回溯上一块 $block = $blockList[0]; $dataFlows = $block->getBlockSummary()->getDataFlowMap(); $dataFlows = array_reverse($dataFlows); return self::encodeSameVarTraceback($varName, $block, $dataFlows); } return self::encodeSameVarTraceback($varName, $block, $dataFlows); } else { //平行结构 //向上找相关变量的净化信息,只有平行块间的变量净化信息相同,才保存 $retarr = array(); foreach ($blockList[0] as $key => $block) { if (count($dataFlows) == 0) { //当前块回溯完毕,回溯上一块 $dataFlows = $block->getBlockSummary()->getDataFlowMap(); $dataFlows = array_reverse($dataFlows); $ret = self::encodeSameVarTraceback($varName, $block, $dataFlows); $dataFlows = array(); } else { $ret = self::encodeSameVarTraceback($varName, $block, $dataFlows); } //得到各个平行结构中的相同函数 if ($key == 0) { if ($ret[0]) { $retarr = $ret['funcs']; } else { return array(false); } } if ($ret[0]) { $temp = array(); foreach ($retarr as $function) { foreach ($ret['funcs'] as $otherfunction) { if ($function == $otherfunction) { array_push($temp, $function); } } } $retarr = $temp; } else { return array(false); } } return array(true, 'funcs' => $retarr); } }