REVIEW
UNKNOWN CODE
WITH
STATIC ANALYSIS
Amersfoort, Netherlands, June 2017
Agenda
Reviewing code
Static analysis for PHP
A session in which you are the hero
Review this code
We don't know what it does
We have never heard about it
We don't run it
We don't know the authors
Can we form an opinion?
How to review code
Reading code is humanly possible : its an art
Unit test are not adapted for review
Dynamic analysis is not fit for review
We need to explore code
We cannot only rely on the current state
Speaker
Damien Seguy
Exakat CTO
Static analysis for PHP
PHP doc author
Ik spreek geen nederlandse
Source code is structured
Source code is a structured database
All we need is tools to query it
This is static analysis
Migration PHP 7.0->7.1
IncompatibilitiesNewfeatures
Appinfo()
List PHP features
Focus on PHP's specifics
PHP Features
Application favorites
Many solutions to the same problem
Impact on PHP is minimal
Generate never-ending discussions
Rule : choose one, stick to it
List of 

directives
Automated code review
Analyze code
Report PHP related problems
Clean code for PHP
Best practices
Security, performance, clean code
in-house, PSR, calisthenics, other inspirations
Code mantras, code kata
PHP Manual
Migration guides
Results by files
Exakat : 350 analysis
Analysis Freq. Here
function __destruct() { throw …} :
0,3 % 0
0.3% 0
function foo($a, $a, $a) {} 2.0% 0
!!(expression) 1.0% 1
substr($a, 2, 4) == 'abc' 9.0% 0
$a ? $b ? $c : $d : $e 11% 0
foreach($a as &$b) {} 15% 6
if (strpos($a, $b)) {} 55% 15
include('file.php') 75% 263
PHP 7.0 compatibility
List of 

directives
Automated code review
Semantic read of the code
Reports interesting issues
Works with AST
Automated code review
PHP 5 / 7
Calisthenics
ClearPHP
Performance
 
 

Semantics and definitions
Removes spaces, comments, documentations
Removes delimiters
( ) { } [ ] " ' ` ; :
Good network to link definition with usage
AST
<?php
class Foo {
    function bar($arg) {
        return StrToUpper($arg + 2);
    }
}
$foo = new Foo();
$foo->bar(__FILE__);
AST diagram
<?php
    $x = source();
    
    if ($x < 10) {
        $y = $x + 1;
        $a = 3;
        $x = corrige($y);
    } else {
        $y = $x;
    }
Flow Control Graph
<?php
    $x = source();
    
    if ($x < 10) {
        $y = $x + 1;
        $a = 3;
        $x = corrige($y);
    } else {
        $y = $x;
    }
$x = source;
if ($x < 10)
$y = $x;
$y = $x + 1;
$x = corrige($y);
end
$a = 3;
start
Data Dependency Graph
<?php
    $x = source();
    
    if ($x < 10) {
        $y = $x + 1;
        $a = 3;
        $x = corrige($y);
    } else {
        $y = $x;
    }
$x = source;
if ($x < 10) $y = $x;$y = $x + 1;
$x = corrige($y);
fin();
Depends onDepends on
Depends
on notDepends on
Depends on
$a = 3;
Depends on
Various AST
PHP7mar : nikic/php5-ast
PHAN : ext/ast (PHP 7 only)
Exakat : AST in a graph database
SonarQube : Java-build AST
PHPstorm : internal IDE AST
PHAN
protected/views/book/admin.php:7 PhanUndeclaredVariable Variable $this is undeclared
Total : 5194 results / 36 types
2967 issues
/protected/views/configurations/_form.php:22
PhanTypeMismatchArgument Argument 1 (pk) is int but EmployeeAttendances::findByPk() takes array|null
defined at core/yiilite.php:7230
475 issues
core/utils/CMarkdownParser.php:81 PhanUndeclaredClassMethod Call to method purify from undeclared class HTMLPurifier
core/utils/CMarkdownParser.php:99 PhanUndeclaredClassMethod Call to method outdent from undeclared class MarkdownExtra_Parse
core/caching/CMemCache.php:111 PhanUndeclaredClassMethod Call to method __construct from undeclared class Memcache
323 issues
protected/controllers/LeadsController.php:352 PhanUndeclaredConstant Reference to undeclared constant MENU_TITLE
protected/controllers/LeadsController.php:353 PhanUndeclaredConstant Reference to undeclared constant MENU_URL
protected/controllers/LeadsController.php:354 PhanUndeclaredConstant Reference to undeclared constant MENU_CLASS
protected/modules/courses/views/courses/left_side.php:49 PhanRedefineFunction Function t
protected/modules/courses/views/studentAttentance/attentstud.php:30 PhanRedefineFunction Function getweek
166 issues
32 issues
PHP 7 helps static analysis
Type hint, return type hint, scalar typehint
Usage of PHPDOC
Consistent behavior of PHP operators
Dynamic code is very difficult to analyze
PHP LINT
php -l <fichier.php>
Paralell executions
jakub-onderka/php-paralell-lint
Various versions of PHP : 7.0, 7.1, 7.2, 5.6, 5.5
Checked 2795 files in 16.4 seconds
Syntax error found in 1 file
------------------------------------------------------------
Parse error: protected/vendors/MPDF/mpdf.php:1417
1415| case 'DEMY': {$format=array(382.68,612.28 ); break;} // 'Demy'
1416| case 'ROYAL': {$format=array(433.70,663.30 ); break;} // 'Royal' f
> 1417| default: $format = false;
1418| }
1419| return $format;
Fatal error: Switch statements may only contain one default clause
PHP LINT - 7.0/1
PHP LINT - 5.4/5/6 - 7.2
No syntax error found ??
0
1.25
2.5
3.75
5
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
0
1
2
3
4
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
0
0.75
1.5
2.25
3
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
0
1.75
3.5
5.25
7
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2 5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
What does this app do?
Inventories of the application
Names for classes, methods, traits, variables,
interfaces…
List of literal in the code
Integers, real, arrays, strings
Errors messages
Classes
[EmployeesController] => 1
[ProductSearchController] => 1
[Services_Twilio_RestException] => 1
[RegisterForm] => 1
[BorrowBook] => 1
[Floor] => 1
[MessageController] => 1
[RInstaller] => 1
[AuthItemForm] => 1
[EmployeesSubjects] => 1
[Services_Twilio_UsageResource] => 1
[EmployeeAttendancesController] => 1
[Logo] => 1
[StudentAdditionalFields] => 1
[AttendanceModule] => 1
[DefaultsubjectsController] => 1
[EmployeeDepartments] => 1
[LogoutController] => 1
[EventsController] => 1
[SmsSettings] => 1
[UserChangePassword] => 1
[ElectiveGroupsController] => 2
[ElectivesController] => 2
[UserController] => 2
[Settings] => 2
[CKEditor] => 2
[CoursesController] => 2
[User] => 2
[UserIdentity] => 3
[SavedsearchesController] => 3
[StudentAttentanceController] => 3
[PDF] => 5
[Message] => 5
[DefaultController] => 22
Variables
[$config] => 288
[$command] => 303
[$proc] => 324
[$c] => 336
[$url] => 337
[$index] => 352
[$type] => 352
[$file] => 361
[$token] => 417
[$time] => 443
[$column] => 474
[$options] => 475
[$className] => 489
[$sql] => 519
[$log] => 544
[$entry] => 575
[$message] => 584
[$attribute] => 587
[$key] => 676
[$params] => 711
[$table] => 858
[$htmlOptions] => 885
[$i] => 1123
[$id] => 1228
[$value] => 1596
[$criteria] => 2072
[$name] => 2250
[$data] => 2368
[$form] => 3393
[$model] => 7075
Also : 

684 used-once variables
Metrics
Provides measures values about the code
Cyclomatic complexity, LOC, Maintenance index
Directories 1143
Files 5982
Size
Lines of Code (LOC) 835199
Comment Lines of Code (CLOC) 252075 (30.18%)
Non-Comment Lines of Code (NCLOC) 583124 (69.82%)
Logical Lines of Code (LLOC) 195283 (23.38%)
Classes 178062 (91.18%)
Average Class Length 29
Minimum Class Length 0
Maximum Class Length 3141
Average Method Length 4
Minimum Method Length 0
Maximum Method Length 879
Functions 1477 (0.76%)
Average Function Length 1
Not in classes or functions 15744 (8.06%)
Cyclomatic Complexity
Average Complexity per LLOC 0.30
Average Complexity per Class 10.82
Minimum Class Complexity 1.00
Maximum Class Complexity 1177.00
Average Complexity per Method 2.65
Minimum Method Complexity 1.00
Maximum Method Complexity 387.00
PHPLOC
PHPMetrics
PHPMetrics
Going even further
Dynamic code
40% of the code is actually constant
Taint analysis
Transpilage : https://github.com/jaytaph/Transphpile
PHP inspections : Integrated in phpStorm
Integrate static analysis in pipeline
List of PHP analyzers
Exakat
Phan
Phploc
PHP 7 cc
PHPmetrics
https://github.com/exakat/
php-static-analysis-tools
Large application
One framework (Yii)
many old libraries (MPDF, PEAR)
Low level of issues
Tend to favorite old PHP features
Backward compatibilities
Deal with school : students, books, elections
open-school.org
Bedankt
http://exakat.io/ - @exakat

Review unknown code with static analysis