Exakat 1.7.2 reviewExakat 1.7.2 Review

The Exakat 1.7.2 version brings more grunt work for the engine, and fewer surprises for your audits. This week, we extended the support for ignored classes to functions and constants: ignore any file in the configuration, and Exakat keeps in mind when it contains definitions. Also, the automated detection of large libraries has been refactored. There are two new reports: History and Perfile. Finally, new in the library, are the magic methods __call and __callstatic, that should always check for method existence before relaying the call. Grass is always greener when you have read the Exakat 1.7.2 review!

Support for ignored functions and constants

Last week, Exakat introduced support for ignored classes, interfaces and traits. When running an Exakat audit, it is possible to ignore files and folders, so as to reduce the amount of code reviewed. Less code, less processing time, and faster reports : all that is good!

Yet, ignoring central files introduces a special type of false positives : the ignored files contained definitions that are important to the audited code. For example, a file containing a library of classes and functions may be ignored while auditing the rest of the code : this library is authored and audited by another team. Then, definitions for those classes are now missing, and reported as such.

With Exakat 1.7.2, all files are scanned for definitions. Those definitions are used to weed out those false positives, and reduce the number of reported issues.

Scanning the ignored files takes less time than auditing them : only their structure and location in the namespaces are taken into account. The rest is ignored (really this time).

Exakat takes into account classes, interfaces, traits, constants and functions. Some more structures may be added to this current list: global variables, in particular : they may be worth collecting too, to avoid unique usage. This is reserved for future development. Feel free to ping use on Slack or @exakat on twitter.

Automatic detections of common libraries

As part of the initial preparation of code for an audit, Exakat examines the content of the file, and automatically ignores a number of large and common libraries.

With the current best practice to use composer, lots of those libraries have migrated to composer.json, and are automatically ignored when checking out a repository : Exakat doesn’t install the related libraries, as they are probably audited on their own, and not as part of the current project.

Yet, some development code repositories hard include some libraries. Sometimes, the library has been packaged with the code for a very long time; or maybe, the library was modified, adapted or fixed locally. It is now an inner part of the code, until it is decoupled enough to be moved to composer, dropped or replaced.

In any case, those libraries are not worth reviewing, as they are not part of the code written for the applications. They also weigh down the audit, by forcing the engine to review long lists of integers, or massive classes.

Exakat detects those libraries, and ignores them automatically, through a file called ‘config.cache’, that is stored at the root of the project. This file should not be edited : in case of doubt, just remove it, and exakat will renew it during the next audit.

History and Perfile Reports

Two new reports are added to Exakat : History and Perfile. They are almost eponymous, yet, let us walk through their usage.

Perfile is another take on the Text report. It reports a list of analysis or ruleset, and displays them file per file, in ascending number of lines. This makes a simple text report, well crafted for developer review : open the mentioned file in your IDE, and then check out all the issues in one file, one by one.

History is a special kind of report : it collects aggregates each time an audit is run. It creates a Sqlite3 database, and initializes it with the current audit. Then, for every new audit, History is called, it appends the same metrics to the SQLite database. After several audits, it shows the evolution of those metrics over an interval of time.

At the moment, History collects the result counts for each analyzer that was running, and a hash table, which contains the general aggregates, such as time to run the audit, PHP version used, exakat version, etc. An extra column was added after the auto-increment id column, which includes a sequence number.

Each audit now includes three identifiers : dump_serial, which is an auto-increment counter, based on the previous found report. dump_time contains a timestamp : it is the moment the history records were added; Finally, dump_id is a random number, that helps differentiate history records if dump_serial or dump_time are confusing.

There is no GUI for the History report yet. At the moment, the best is to look inside the database, and query it with SQL.

History is also meant to hold a condensed snapshot of an audit. In six months, we won’t need to know where were the exact issues, but we’ll be more interested in how many of them were found. If you want to keep the full detail of each audit, make a copy of the ‘dump.sqlite’ database in a safe place.

Check for Methods With __call()

Exakat 1.7.2 comes with two new analyses : one targeting ‘unsupported operand types’, which spots one of the PHP Fatal Error before execution. This error often happens at lint time, when an array is added to an integer, or invalid types are combined together with an operator. It may also happen at execution time : this is a classic ‘Lint but won’t execute’ type of analysis. Exakat finds more of those errors than PHP lint.

The other analysis concerns the magic methods __call() and __callStatic(). Both are magic methods for PHP classes : they are used for Method overloading. When a method is called on an object, PHP first checks the available methods and their visibility. When no method is available, PHP checks for the __call() method (or the __callStatic() in the case of a static method call). This magic method is then called with the name of the called, yet unavailable, method name, and the arguments, as an array. At that point, __call() may decide what to do with the call : rename the method, use a fallback, relay to another object, log an error, etc.

 
<?php

class x {     
    function __call($a, $b) {         
        return $this->$a(...$b);
    }

    private function foo() { return 1; }
}

//valid method call print 
(new x)->dd();

//invalid method call 
print (new x)->foo();

?>

At introduction time, __call() is easy to use as the relay happens between few parts of the code : few methods calls, few defined methods. As the code grows, it is easy to lose track of all the methods names, or make a typo in the method name. When this happens, it leads to an infinite loop : method typo leads to call to __call(), which relays to another method with a typo’s, which falls back on __call(), which… You get the drill. It may fill up your memory, or hit xdebug‘s max nesting level

__call() and __callStatic() should always check that the called method exists, and is available before relaying the method call. The best method is method_exists, which takes a class or an object of the class, and the name of the method. You may also use a white list.

The Weekly Audits : 2019, Week #13

Exakat includes a ‘weekly’ report : this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you : you’ll find programmers facing the same challenges.

To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.

# Init the project (skip when it is already done)    
php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git 

# Run the project (skip when it is already done)    
php exakat.phar project -p <yourproject> 

# Export the weekly project (every monday)    
php exakat.phar report -p <yourproject> -format Weekly 

# Open projects/<yourproject>/weekly/index.html in your browser    

Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming

Weekly recommendations for PHP code review : 2019, week 2019-13

Happy PHP Code Reviews

All the 356 analyzers are presented in the docs, including the inevitable : Empty blocks : totally empty blocks, part of a control structures.

It is a routine bug, and source of overwork in the code : 57% of applications are using empty blocks.

You can check all of the Exakat reports at the gallery: exakat gallery.

Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.