Conditional Code Analysis
Categories
As briefly introduced at end of advanced detection chapter, we will learn now that there are 3 categories of conditional code that could give wrong result, if there are not catched properly.
These categories are :
-
function (
cond_code = 1
)A quick example:
<?php
if (function_exists('debug_backtrace')) {
$backtrace = debug_backtrace();
} else {
$backtrace = false;
}
?> -
extension (
cond_code = 2
)A quick example:
<?php
if (extension_loaded('sqlite') == false) {
$prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '';
dl($prefix . 'sqlite.' . PHP_SHLIB_SUFFIX);
echo 'SQLite version : ' . sqlite_libversion();
}
?> -
constant (
cond_code = 4
)A quick example:
<?php
if (defined('DATE_RSS') {
$date_format = DATE_RSS;
} else {
$date_format = 'D, j M Y H:i:s O';
}
// will display something like "Sat, 26 Jul 2008 16:56:24 +0200"
echo date($date_format, mktime(0, 0, 0, 7, 26, 2008));
?>
How to catch them with web interface
At the beginning of first version that catch conditional code, there were only
3 options: ignore_functions
, ignore_extensions
and ignore_constants
.
Incovenient with these options, is that you should know the source code to parse, and identify whose functions, extensions or constants to avoid.
Version 1.7.0 of API has introduced the ability to add name patterns to identify
all or part of functions, extensions, constants to ignore from parsing.
You should use now these options: ignore_functions_match
,
ignore_extensions_match
or ignore_constants_match
.
Let's take a look with an example, how it's easy to catch whatever you want to exclude from parsing. We will take again example of PEAR::HTML_CSS 1.5.1 package already seen in advanced directory detection .
<?php
require_once 'PHP/CompatInfo.php';
$datasource = '/tmp/HTML_CSS-1.5.1';
$options = array(
'ignore_dirs' => array('examples', 'tests'),
'ignore_functions_match' => array('function_exists', array('/.*/')),
'ignore_extensions_match' => array('extension_loaded', array('/.*/')),
'ignore_constants_match' => array('defined', array('/.*/')),
);
$pci = new PHP_CompatInfo();
$pci->parseData($datasource, $options);
?>
Here we catch all standard conditional code (function_exists
,
extension_loaded
, defined
) what match
all names (regular expression given by array('/.*/')
).
To catch what ever function you want, use
preg_match
rather thanfunction_exists
.It's also true for
extension_loaded
anddefined
With preg_match you are really free to ignore a single function, a group set or all functions, only by giving the good name pattern.
Example to ignore all functions prefixed by xdebug_ :
<?php
require_once 'PHP/CompatInfo.php';
$datasource = '/tmp/HTML_CSS-1.5.1';
$options = array(
'ignore_functions_match' => array('preg_match', array('/^xdebug_/')),
);
$pci = new PHP_CompatInfo();
$pci->parseData($datasource, $options);
?>
How to catch them with CLI
If you use the command-line parser with pci script, the solution is a bit different.
To catch cond_code = 1 (function), you must run the command
pci
-inm functions-match.txt
where functions-match.txt
is a text file, that identify
on each line a new condition.
Each blank line or beginning with ;
will be skipped
(proceed as comment line like in php.ini)
If first non blank character is an equal sign (=), then you can catch what ever function you want with a preg_match condition (see xdebug example in previous section (web interface)
Example of text file contents
;=^xdebug_ ;=alias$ .* ;file_put_contents
Do not confuse a regular expression beginning with equal sign (=), and the same line without =.
In first case you will catch all functions that match the name pattern given found in all source code, while second case try to catch only matches found with
if function_exists('')
condition.It's also true for extensions and constants, we will see them now.
To catch cond_code = 2 (extension), you must run the command
pci
-iem extensions-match.txt
where extensions-match.txt
is a text file, that identify
on each line a new condition.
Each blank line or beginning with ;
will be skipped
(proceed as comment line like in php.ini)
If first non blank character is an equal sign (=), then you can catch what ever extension you want with a preg_match condition.
Example of text file contents
;=xdebug ;sqlite =gd ;=sapi_apache
To catch cond_code = 4 (constant), you must run the command
pci
-icm constants-match.txt
where constants-match.txt
is a text file, that identify
on each line a new condition.
Each blank line or beginning with ;
will be skipped
(proceed as comment line like in php.ini)
If first non blank character is an equal sign (=), then you can catch what ever constant you want with a preg_match condition.
Example of text file contents
=PHP_EOL =DATE_RSS ;FILE_FIND_VERSION