Page MenuHomeWickedGov Phorge

ReturnObjectsCollectVisitor.php
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

ReturnObjectsCollectVisitor.php

<?php
namespace SecurityCheckPlugin;
use ast\Node;
use Phan\Exception\IssueException;
use Phan\Exception\NodeException;
use Phan\Language\Element\TypedElementInterface;
use Phan\Language\Element\Variable;
use Phan\PluginV3\PluginAwareBaseAnalysisVisitor;
/**
* Given a return statements, return a list of phan objects that are returned by it.
*
* @todo This should also do what matchTaintToParam currently does
*/
class ReturnObjectsCollectVisitor extends PluginAwareBaseAnalysisVisitor {
use TaintednessBaseVisitor;
/** @var TypedElementInterface[] */
private $buffer = [];
/**
* @param Node $node
* @return TypedElementInterface[]
*/
public function collectFromNode( Node $node ): array {
assert( $node->kind === \ast\AST_RETURN );
$this->buffer = [];
$this( $node->children['expr'] );
return $this->buffer;
}
/**
* @inheritDoc
*/
public function visitProp( Node $node ): void {
$this->handleReturnedObject( $this->getPropFromNode( $node ) );
}
/**
* @inheritDoc
*/
public function visitNullsafeProp( Node $node ): void {
$this->handleReturnedObject( $this->getPropFromNode( $node ) );
}
/**
* @inheritDoc
*/
public function visitStaticProp( Node $node ): void {
$this->handleReturnedObject( $this->getPropFromNode( $node ) );
}
/**
* @inheritDoc
*/
public function visitVar( Node $node ): void {
$this->handleVarNode( $node );
}
/**
* @inheritDoc
*/
public function visitClosureVar( Node $node ): void {
// FIXME Is this needed?
$this->handleVarNode( $node );
}
/**
* @param Node $node
*/
private function handleVarNode( Node $node ): void {
$cn = $this->getCtxN( $node );
if ( Variable::isHardcodedGlobalVariableWithName( $cn->getVariableName() ) ) {
return;
}
try {
$this->handleReturnedObject( $cn->getVariable() );
} catch ( NodeException | IssueException $e ) {
$this->debug( __METHOD__, "variable not in scope?? " . $this->getDebugInfo( $e ) );
}
}
/**
* @inheritDoc
*/
public function visitEncapsList( Node $node ): void {
foreach ( $node->children as $child ) {
if ( $child instanceof Node ) {
$this( $child );
}
}
}
/**
* @inheritDoc
*/
public function visitArray( Node $node ): void {
foreach ( $node->children as $child ) {
if ( $child instanceof Node ) {
$this( $child );
}
}
}
/**
* @inheritDoc
*/
public function visitArrayElem( Node $node ): void {
if ( $node->children['key'] instanceof Node ) {
$this( $node->children['key'] );
}
if ( $node->children['value'] instanceof Node ) {
$this( $node->children['value'] );
}
}
/**
* @inheritDoc
*/
public function visitCast( Node $node ): void {
// Future todo might be to ignore casts to ints, since
// such things should be safe. Unclear if that makes
// sense in all circumstances.
if ( $node->children['expr'] instanceof Node ) {
$this( $node->children['expr'] );
}
}
/**
* @inheritDoc
*/
public function visitDim( Node $node ): void {
if ( $node->children['expr'] instanceof Node ) {
// For now just consider the outermost array.
// FIXME. doesn't handle tainted array keys!
$this( $node->children['expr'] );
}
}
/**
* @inheritDoc
*/
public function visitUnaryOp( Node $node ): void {
if ( $node->children['expr'] instanceof Node ) {
$this( $node->children['expr'] );
}
}
/**
* @inheritDoc
*/
public function visitBinaryOp( Node $node ): void {
if ( $node->children['left'] instanceof Node ) {
$this( $node->children['left'] );
}
if ( $node->children['right'] instanceof Node ) {
$this( $node->children['right'] );
}
}
/**
* @inheritDoc
*/
public function visitConditional( Node $node ): void {
if ( $node->children['true'] instanceof Node ) {
$this( $node->children['true'] );
}
if ( $node->children['false'] instanceof Node ) {
$this( $node->children['false'] );
}
}
/**
* @inheritDoc
*/
public function visitCall( Node $node ): void {
$this->handleCall( $node );
}
/**
* @inheritDoc
*/
public function visitMethodCall( Node $node ): void {
$this->handleCall( $node );
}
/**
* @inheritDoc
*/
public function visitStaticCall( Node $node ): void {
$this->handleCall( $node );
}
/**
* @inheritDoc
*/
public function visitNullsafeMethodCall( Node $node ): void {
$this->handleCall( $node );
}
/**
* @param Node $node @phan-unused-param
*/
private function handleCall( Node $node ): void {
// TODO If the func being called already has retObjs, we might add them.
}
/**
* @inheritDoc
*/
public function visitPreDec( Node $node ): void {
$this->handleIncOrDec( $node );
}
/**
* @inheritDoc
*/
public function visitPreInc( Node $node ): void {
$this->handleIncOrDec( $node );
}
/**
* @inheritDoc
*/
public function visitPostDec( Node $node ): void {
$this->handleIncOrDec( $node );
}
/**
* @inheritDoc
*/
public function visitPostInc( Node $node ): void {
$this->handleIncOrDec( $node );
}
/**
* @param Node $node
*/
private function handleIncOrDec( Node $node ): void {
$children = $node->children;
assert( count( $children ) === 1 );
$this( reset( $children ) );
}
/**
* @param TypedElementInterface|null $el
*/
private function handleReturnedObject( ?TypedElementInterface $el ): void {
if ( $el ) {
$this->buffer[] = $el;
}
}
}

File Metadata

Mime Type
text/x-php
Expires
Sat, May 16, 21:22 (1 d, 13 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
aa/62/284b4308d7f21053880cf9fc541c
Default Alt Text
ReturnObjectsCollectVisitor.php (5 KB)

Event Timeline