DivisionByOne   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 47
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 47
ccs 0
cts 15
cp 0
rs 10
c 0
b 0
f 0
wmc 5
lcom 0
cbo 3

2 Methods

Rating   Name   Duplication   Size   Complexity  
A pass() 0 22 4
A getRegister() 0 9 1
1
<?php
2
3
namespace PHPSA\Analyzer\Pass\Expression;
4
5
use PhpParser\Node\Expr;
6
use PHPSA\Analyzer\Helper\DefaultMetadataPassTrait;
7
use PHPSA\Analyzer\Pass\AnalyzerPassInterface;
8
use PHPSA\Context;
9
10
class DivisionByOne implements AnalyzerPassInterface
11
{
12
    use DefaultMetadataPassTrait;
13
14
    const DESCRIPTION = 'Checks for division by 1. For example: `$x/1`, `$x%true`';
15
16
    /**
17
     * @param Expr $expr
18
     * @param Context $context
19
     * @return bool
20
     */
21
    public function pass(Expr $expr, Context $context)
22
    {
23
        $compiler = $context->getExpressionCompiler();
24
25
        if ($expr instanceof Expr\AssignOp) {
26
            $right = $compiler->compile($expr->expr);
27
        } elseif ($expr instanceof Expr\BinaryOp) {
28
            $right = $compiler->compile($expr->right);
29
        }
30
31
        if ($right->getValue() == 1) {
0 ignored issues
show
Bug introduced by
The variable $right does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
32
            $context->notice(
33
                'division_by_one',
34
                "You are trying to divide by one",
35
                $expr
36
            );
37
38
            return true;
39
        }
40
        
41
        return false;
42
    }
43
44
    /**
45
     * @return array
46
     */
47
    public function getRegister()
48
    {
49
        return [
50
            Expr\BinaryOp\Div::class,
51
            Expr\BinaryOp\Mod::class,
52
            Expr\AssignOp\Div::class,
53
            Expr\AssignOp\Mod::class,
54
        ];
55
    }
56
}
57