Created
December 6, 2018 14:32
-
-
Save SukkaW/45f85999903d8fd743b68d3e0141f47b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
// FIXME: Make this a proper app with unit-tests | |
require_once 'simple_html_dom.php'; | |
exit(main($argv)); | |
/** | |
* Scan a series of files for suspicious code | |
* | |
* example: find templates -name '*.tpl' | xargs php tools/scripts/tpl-lint | |
* | |
* @param array $argv | |
* @return int | |
*/ | |
function main($argv) { | |
$files = $argv; | |
array_shift($files); // skip program name | |
foreach ($files as $file) { | |
check_tpl($file, function($code, $message) use ($file) { | |
printf("[%s] %s\n", $file, $message); | |
}); | |
} | |
return 0; | |
} | |
/** | |
* Scan a file for suspicious code | |
* | |
* @param string $file | |
* @param callable $reporter | |
* @return void | |
*/ | |
function check_tpl($file, $reporter) { | |
$html = file_get_html($file); | |
foreach ($html->find('a') as $a) { | |
check_a($a, $reporter); | |
} | |
} | |
/** | |
* Scan an <A> tag | |
* | |
* @param object $a | |
* @param callable $reporter | |
* @return void | |
*/ | |
function check_a($a, $reporter) { | |
if (!$a->hasAttribute('href')) { | |
// anchor, don't care | |
return; | |
} | |
$href = trim($a->getAttribute('href')); | |
if (preg_match('/javascript:/', $href)) { | |
$reporter('javascript-url', "<a> has javascript url: $href"); | |
return; | |
} | |
if ($href == '#' && $a->hasAttribute('onclick')) { | |
$onclick = $a->getAttribute('onclick'); | |
if (!js_returns_false($onclick) && !js_returns_func($onclick)) { | |
$reporter('a-no-return', "<a> has href=# but handler fails to return false: $onclick"); | |
return; | |
} | |
} | |
if ($href != '#' && $a->hasAttribute('onclick')) { | |
$onclick = $a->getAttribute('onclick'); | |
$reporter('a-double-action', "<a> has both URL ($href) and onclick ($onclick)"); | |
return; | |
} | |
} | |
/** | |
* Determine if snippet of JS returns strictly false | |
* @param $js | |
* @return bool | |
*/ | |
function js_returns_false($js) { | |
return | |
// last in a series of statements | |
preg_match('/; *return +false *; *$/', $js) | |
|| | |
// only statement | |
preg_match('/^ *return +false *;? *$/', $js); | |
} | |
/** | |
* Determine if snippet of JS returns a function call | |
* @param $js | |
* @return int | |
*/ | |
function js_returns_func($js) { | |
return preg_match('/^ *return +[a-zA-Z0-9\._$]+\(/', $js); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment