|
12 | 12 | * obviously variable-interpolated SQL on a single line. |
13 | 13 | */ |
14 | 14 |
|
| 15 | +it('raw-interpolated pattern matches known unsafe db call strings', function () { |
| 16 | + $pattern = '/\bdb_(?:execute|fetch_row|fetch_assoc|fetch_cell)\s*\(\s*(["\']).*\$[A-Za-z_{]/'; |
| 17 | + |
| 18 | + $unsafe = [ |
| 19 | + 'db_execute("SELECT * FROM thold WHERE id=$id")', |
| 20 | + "db_fetch_row('SELECT id FROM thold WHERE name=$name')", |
| 21 | + 'db_fetch_cell("SELECT value FROM thold WHERE host_id=$host_id")', |
| 22 | + 'db_fetch_assoc("SELECT * FROM thold WHERE template_id={$template_id}")', |
| 23 | + ]; |
| 24 | + |
| 25 | + foreach ($unsafe as $line) { |
| 26 | + expect(preg_match($pattern, $line))->toBe(1, "Expected unsafe pattern match on: {$line}"); |
| 27 | + } |
| 28 | +}); |
| 29 | + |
| 30 | +it('raw-interpolated pattern does not match safe db call strings', function () { |
| 31 | + $pattern = '/\bdb_(?:execute|fetch_row|fetch_assoc|fetch_cell)\s*\(\s*(["\']).*\$[A-Za-z_{]/'; |
| 32 | + |
| 33 | + $safe = [ |
| 34 | + 'db_execute_prepared("SELECT * FROM thold WHERE id = ?", array($id))', |
| 35 | + 'db_fetch_row_prepared("SELECT id FROM thold WHERE name = ?", array($name))', |
| 36 | + 'db_execute("SELECT * FROM thold WHERE id = ?")', |
| 37 | + 'db_execute("SELECT COUNT(*) FROM thold")', |
| 38 | + ]; |
| 39 | + |
| 40 | + foreach ($safe as $line) { |
| 41 | + expect(preg_match($pattern, $line))->toBe(0, "Expected no pattern match on safe call: {$line}"); |
| 42 | + } |
| 43 | +}); |
| 44 | + |
| 45 | +it('comment-skip logic excludes full-line comments from interpolation checks', function () { |
| 46 | + $commentLines = [ |
| 47 | + '// db_execute("SELECT * FROM thold WHERE id=$id")', |
| 48 | + ' // db_execute("SELECT * FROM thold WHERE id=$id")', |
| 49 | + ' * db_execute("SELECT * FROM thold WHERE id=$id")', |
| 50 | + ' * example db_fetch_row("SELECT id FROM thold WHERE host=$host")', |
| 51 | + '# db_execute("SELECT * FROM thold WHERE id=$id")', |
| 52 | + ]; |
| 53 | + |
| 54 | + foreach ($commentLines as $line) { |
| 55 | + $trimmed = ltrim($line); |
| 56 | + $isSkipped = strpos($trimmed, '//') === 0 |
| 57 | + || strpos($trimmed, '*') === 0 |
| 58 | + || strpos($trimmed, '#') === 0; |
| 59 | + |
| 60 | + expect($isSkipped)->toBeTrue("Full-line comment should be skipped: {$line}"); |
| 61 | + } |
| 62 | +}); |
| 63 | + |
15 | 64 | it('does not introduce single-line interpolated db_* calls in hardened files', function () { |
16 | | - $targetFiles = array( |
| 65 | + $targetFiles = [ |
17 | 66 | 'poller_thold.php', |
18 | 67 | 'setup.php', |
19 | 68 | 'thold.php', |
20 | 69 | 'thold_graph.php', |
21 | | - ); |
| 70 | + ]; |
22 | 71 |
|
23 | 72 | $rawInterpolatedPattern = '/\bdb_(?:execute|fetch_row|fetch_assoc|fetch_cell)\s*\(\s*(["\']).*\$[A-Za-z_{]/'; |
24 | 73 | $preparedPattern = '/\bdb_(?:execute|fetch_row|fetch_assoc|fetch_cell)_prepared\s*\(/'; |
|
40 | 89 | } |
41 | 90 |
|
42 | 91 | $hasInterpolatedRawCall = preg_match($rawInterpolatedPattern, $line) === 1; |
43 | | - $hasPreparedCall = preg_match($preparedPattern, $line) === 1; |
| 92 | + $hasPreparedCall = preg_match($preparedPattern, $line) === 1; |
44 | 93 |
|
45 | 94 | expect($hasInterpolatedRawCall && !$hasPreparedCall)->toBeFalse( |
46 | 95 | sprintf('File %s contains an interpolated raw db_* call at line %d', $relativeFile, $lineNumber + 1) |
|
0 commit comments