Review unknown code with static analysis - bredaphp

Post on 26-Jan-2017

90 views 2 download

Transcript of Review unknown code with static analysis - bredaphp

Review unknown code with static analysis

Breda, Nederlands, Dec. 2016

Agenda

Reviewing code

Static analysis for PHP

A session in which you are the hero

Review this project

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 have 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

Den Haag : ik ben een boterham

Static analysis for PHP : SCAP

PHP doc author

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

Inco

mpa

tibilit

iesNe

w fe

atur

es

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 5982 files in 28.4 seconds Syntax error found in 4 files

------------------------------------------------------------ Parse error: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/False.php:22 20| * @api 21| */ > 22| class False extends IsFalse 23| { 24| } Fatal error: Cannot use 'False' as class name as it is reserved ------------------------------------------------------------ Parse error: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/Null.php:22 20| * @api 21| */ > 22| class Null extends IsNull 23| { 24| } Fatal error: Cannot use 'Null' as class name as it is reserved ------------------------------------------------------------ Parse error: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/True.php:22 20| * @api 21| */ > 22| class True extends IsTrue 23| { 24| } Fatal error: Cannot use 'True' as class name as it is reserved ------------------------------------------------------------ Parse error: /vendor_user/windid_client/src/windid/service/base/WindidUtility.php:93 91| $imageInfo = @getimagesize($file); 92| $exts = array('1'=>'gif', '2'=>'jpg', '3'=>'png'); > 93| if (!isset($exts[$imageInfo[2]])) continue; 94| $ext = $exts[$imageInfo[2]]; 95| $filename = rand(1000,9999). '.'.$ext; Fatal error: 'continue' not in the 'loop' or 'switch' context

PHP LINT - 7.0/1/2

Checked 5982 files in 29.7 seconds Syntax error found in 1 file

------------------------------------------------------------ Parse error: /vendor2/mockery/mockery/tests/Mockery/MockingVariadicArgumentsTest.php:52 50| abstract class TestWithVariadicArguments 51| { > 52| public function foo(...$bar) 53| { 54| return $bar; Unexpected '.', expecting '&' or variable (T_VARIABLE)

PHP LINT - 5.5

PHP LINT - 5.6Checked 5982 files in 31 seconds No syntax error found

PHP LINT

Not compatible with PHP 7.0 +

Not compatible with PHP 5.5-

Uses Symfony

@getimagesize ? vendor2 ?

5982 files

Metrics

PHPloc, PHPmetrics, PHP MD

Provides global values about the code

Cyclomatic complexity, LOC…

PHPLOC 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 Dependencies Global Accesses 2158 Global Constants 1738 (80.54%) Global Variables 31 (1.44%) Super-Global Variables 389 (18.03%) Attribute Accesses 50986 Non-Static 49206 (96.51%) Static 1780 (3.49%) Method Calls 113735 Non-Static 103683 (91.16%) Static 10052 (8.84%)

Structure Namespaces 851 Interfaces 693 Traits 11 Classes 5245 Abstract Classes 301 (5.74%) Concrete Classes 4944 (94.26%) Methods 39581 Scope Non-Static Methods 37468 (94.66%) Static Methods 2113 (5.34%) Visibility Public Methods 31500 (79.58%) Non-Public Methods 8081 (20.42%) Functions 1185 Named Functions 306 (25.82%) Anonymous Functions 879 (74.18%) Constants 2658 Global Constants 361 (13.58%) Class Constants 2297 (86.42%)

PHPMetrics

PHPMetrics

Automated code review

PHP code review PHP code

regex reads PHP

Extract interesting points

Works with keywords

PHP7cc, grep

php7ccFile: /vendor_user/windid_client/wind/convert/WindGeneralConverter.php > Line 33: PHP 4 constructors are now deprecated public function WindGeneralConverter($sourceLang = '', $targetLang = '', $forceTable = false) { }

File: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/Null.php > Line 22: Reserved name "null" used as a class, interface or trait name class Null extends \Symfony\Component\Validator\Constraints\IsNull { }

File: /vendor_user/windid_client/wind/filter/WindHandlerInterceptorChain.php > Line 61: Function argument(s) returned by "func_get_args" might have been modified func_get_args();

File: /vendor_user/windid_client/wind/http/session/handler/WindSessionHandler.php > Line 156: Check that callbacks that are passed to "session_set_save_handler" and return false or -1 (if any) operate correctly session_set_save_handler(array($this, 'open'), array($this, 'close'), array($this, 'read'), array($this, 'write'), array($this, 'destroy'), array($this, 'gc'));

File: /vendor_user/windid_client/wind/security/WindMcryptCbc.php > Line 31: Removed function "mcrypt_cbc" called mcrypt_cbc(MCRYPT_DES, $key, $string, MCRYPT_ENCRYPT, $iv); > Line 49: Removed function "mcrypt_cbc" called mcrypt_cbc(MCRYPT_DES, $key, $string, MCRYPT_DECRYPT, $iv);

Total : 83 issues

Automated code review

Semantic read of the code

Reports interesting issues

Works with AST

PHP7mar, Phan, exakat

Automated code review

PHP 5 / 7 Calisthenics ClearPHP

Performance

AST

<?php

class Foo { function bar($arg) { return \StrToUpper($arg + 2); } }

$foo = new Foo(); $foo->bar(__FILE__);

?>

Semantics and definitions

PHP7mar : nikic/php5-ast

PHAN : ext/ast (PHP 7 only)

Exakat : AST in a graph database

SonarQube : Java-build AST

PHPstorm : internal IDE AST

Semantics and definitions

Removes spaces, comments, documentations

Removes delimiters

( ) { } [ ] " ' ` ; :

Good network to link definition with usage

PHANsrc/Org/OrgBundle/Controller/OrgController.php:12 PhanTypeMismatchArgument Argument 1 (data) is bool but \Org\OrgBundle\Controller\OrgController::createJsonResponse() takes array defined at src/Topxia/WebBundle/Controller/BaseController.php:120

Total : 13315 results1235 issues

vendor_user/windid_client/wind/mail/protocol/WindPop3.php:186 PhanUndeclaredTypeParameter Parameter of undeclared type \baoolean

276 issues

vendor_user/windid_client/wind/base/WindFactory.php:325 PhanTypeArraySuspicious Suspicious array access to bool

184 issues

vendor2/imagine/imagine/lib/Imagine/Image/AbstractLayers.php:49 PhanParamSignatureMismatch Declaration of function get($offset) should be compatible with function get(int $offset) : \Imagine\Image\ImageInterface defined in vendor2/imagine/imagine/lib/Imagine/Image/LayersInterface.php:97

src/Classroom/ClassroomBundle/Controller/ClassroomAdminController.php:84 PhanUndeclaredMethod Call to undeclared method \Classroom\ClassroomBundle\Controller \ClassroomAdminController::createErrorResponse

1919 issues

808 issues

PHAN [PhanRedefineFunction] => 31 [PhanTypeMismatchForeach] => 31 [PhanUndeclaredClassInstanceof] => 32 [PhanDeprecatedFunction] => 43 [PhanUndeclaredClassConstant] => 49 [PhanUndeclaredTypeProperty] => 60 [PhanParamSignatureMismatchInternal] => 79 [PhanUndeclaredClassCatch] => 94 [PhanParamTooMany] => 101 [PhanUndeclaredFunction] => 102 [PhanTypeMissingReturn] => 126 [PhanStaticCallToNonStatic] => 164 [PhanTypeArraySuspicious] => 184 [PhanTypeMismatchDefault] => 194 [PhanNonClassMethodCall] => 202 [PhanUndeclaredTypeParameter] => 276 [PhanUndeclaredConstant] => 417 [PhanUndeclaredVariable] => 432 [PhanTypeMismatchProperty] => 530 [PhanUndeclaredMethod] => 808 [PhanTypeMismatchArgumentInternal] => 854 [PhanUndeclaredClassMethod] => 1082 [PhanTypeMismatchReturn] => 1236 [PhanTypeMismatchArgument] => 1716 [PhanParamSignatureMismatch] => 1840 [PhanUndeclaredProperty] => 2485

53 analyses

PHANsrc/Classroom/Service/Classroom/Tests/ClassroomReviewServiceTest.php:227 PhanDeprecatedFunction Call to deprecated function \Classroom\Service\Classroom\Tests\ClassroomReviewServiceTest::setExpectedException()

defined at vendor/phpunit/phpunit/src/Framework/TestCase.php:466

43 issues

PHP 7 helps SCAP

Type hint, return type hint, scalar typehint

Phan understands PHPDOC

Dynamic code is very difficult to analyze

Flow Control diagram

Handle the way the code is executed

Based on AST, adds sequence tracking

Applied in RIPS

<?php     $x = source();          if ($x < 10) {         $y = $x + 1;         $x = corrige($y);     } else {         $y = $x;     }

Flow Control Graph

$x = source();

if ($x < 10) 

$y = $x + 1;

$x = corrige($y);

$y = $x;

PHP

Exit

ElseThen

<?php     $x = source();          if ($x < 10) {         $y = $x + 1;         $x = corrige($y);     } else {         $y = $x;     }

Program Dependency Graph

$x = source();

if ($x < 10) 

$y = $x + 1;

$x = corrige($y);

$y = $x;Depend de $x

Depend de $x

Depend de $y

Depend de $x

Depend de $x

Depend de $x

<?php     $x = source();          if ($x < 10) {         $y = $x + 1;         $x = corrige($y);     } else {         $y = $x;     }

What about PHP?

Most of those analysis focus on informatics concepts

Some analysis focus on PHP's specifics

Common practices

Special PHP gotchas

Exakat analysisfunction __destruct() { throw …} : 0,5%

function foo($a, $a, $a) {} : 0,5%

!!(expression) : 7.4%

substr($a, 2, 4) == 'abc' : 9 %

$a ? $b ? $c : $d : $e ; 10%

foreach($a as &$b) {} : 21%

if (strpos($a, $b)) {} : 51 %

include('file.php') : 52%

Clean code for PHP

Best practices

in-house, PSR, calisthenics, other inspirations

Code mantras, code kata

PHP Manual

Migration guides

PHP

List of used PHP features

PHP

List of directives

Project preferences

List of directives

What does this app do?

Welcome to the inventories

List of literal in the code

Integers, real, arrays, strings

Names for classes, methods, traits, variables, interfaces…

Error

String used with exit, die and new Exception()

Variables

$orderBy 685 $token 690 $response 721 $paginator 752 $temp 828 $params 891 $value 925 $type 955 $thread 968 $order 982 $member 1042 $classroom 1115 $limit 1222 $start 1320 $currentUser 1334 $userId 1352 $file 1391 $data 1408 $i 1494 $lesson 1504 $sql 1528 $courseId 1626 $key 1716 $fields 2214 $result 2600 $course 2742 $request 3219 $id 3529 $conditions 3870 $user 4505

Also : 271 used-once variables

ClassesOrderServiceTest 2 FileController 2 ClassroomDataTag 2 LiveCourseController 2 UploadFileController 2 NoteController 2 BlockController 2 OrderLogDaoImpl 2 OpenCourseController 2 FileFilter 2 CourseOrderController 2 Member 2 CoinController 2 ThreadServiceTest 3 BaseProcessor 3 MobileController 3 UserController 3 CategoryDaoImpl 3 CourseReviewController 3 TeacherController 3 AlipaySubmit 3 ThreadServiceImpl 3 ThreadPostDaoImpl 3 AlipayNotify 3 ThreadDaoImpl 3 CourseController 5 DefaultController 5 DefaultControllerTest 5 Configuration 6

Comparisons

none 9 vip 10 .. 10 yes 10 material 11 coin 11 created 11 teacher 12 closed 12 error 13 1 14 RMB 15 0 16 paid 16 lesson 18 liveOpen 19 trend 19 cloud 19 ok 20 Coin 21 classroom 22 video 25 self 25 testpaper 27 success 32 live 32 course 39 published 43 _empty_ 71 POST 237

Strings used in comparisons $a == 'ok'

Occurrences counts

Going further

Deptrac

Check that classes stay within their layer

Manual configuration

Until frameworks define layers

Going even furtherDynamic code

40% of the code is actually constant

Transpilage : https://github.com/jaytaph/Transphpile

PHP inspections : Integrated in phpStorm

sensio labs insight : Static analysis for Symfony

Integrate static analysis in IC

Liste des SCAP citésDeptrac

Exakat

PHP7mar

Phan

PHP Inspections

Phploc

PHPMD

PHP 7 cc

PHPmetrics

RIPS

Transphpile

Edusoho

Bedankt!http://exakat.io/ - @exakat

https://joind.in/talk/d5b2c