/[drupal]/contributions/tricks/code-checker/code-checker.php
ViewVC logotype

Contents of /contributions/tricks/code-checker/code-checker.php

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations) (download) (as text)
Tue Oct 24 18:35:10 2006 UTC (3 years, 1 month ago) by killes
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +2 -2 lines
File MIME type: text/x-php
fix path
1 #!/usr/bin/php
2 <?php
3 // $Id: code-checker.php,v 1.5 2006/10/24 18:34:20 killes Exp $
4 // Usage: ./code-checker.php <modules/my-module> <my-report.txt>
5
6 /**
7 * Check SQL query prefixes.
8 */
9 function check_sql_prefix($lineno, $line) {
10 if ((strstr($line, 'db_query(') && strstr($line, 'pager_query(') && strstr($line, 'db_query_range(')) && // begin of SQL query
11 strstr($line, ');') && // end of SQL query
12 (strstr($line, 'INSERT') || strstr($line, 'UPDATE') || strstr($line, 'DELETE')) &&
13 !strstr($line, '{')) { // check for '{'
14 report(" - The SQL query at line $lineno does not wrap its table names in '{}' and will fail to work with database prefixing.\n $line\n");
15 }
16 }
17
18 /**
19 * Check SQL query prefixes.
20 */
21 function check_camel_case($lineno, $line) {
22 if (word($line, 0) == 'function') {
23 // Extract the function name:
24 $name = substr(word($line, 1), 0, strpos(word($line, 1), '('));
25
26 // Check the function name:
27 if (ereg("[^a-z0-9_\$()]", $name)) {
28 report(" - The name of the function '$name' uses 'camel case'-style which does not conform Drupal's standards. Use lower-case names and separate words using an underscore.\n\n");
29 }
30 }
31 }
32
33 function check_else_clause($lineno, $line) {
34 if (strstr($line, '} else')) {
35 report(" - The else-clause at line $lineno puts '}' and 'else' on the same line. To conform Drupal's coding conventions they should be on separate lines.\n\n");
36 }
37 }
38
39 function check_db_wrapper($lineno, $line) {
40 if (preg_match('|["\']SELECT|', $line)) {
41 preg_match_all('|(["\'])SELECT [[:print:]]*;|', $line, $select, PREG_SET_ORDER);
42 if (isset($select[0])) {
43 if(preg_match_all("|FROM ([[:print:]]*) WHERE|U", $select[0][0], $from, PREG_SET_ORDER)) {
44 if (strstr($from[0][1], '$')) {
45 report(" - The SELECT query at line $lineno is potentially insecure as it contains a variable in the FROM statement and does not use our database query wrapper properly.\n $line\n");
46 }
47 }
48 else if(preg_match_all("|FROM ([[:print:]]*)". $select[0][1] ."|U", $select[0][0], $from, PREG_SET_ORDER)) {
49 if (strstr($from[0][1], '$')) {
50 report(" - The SELECT query at line $lineno is potentially insecure as it contains a variable in the FROM statement and does not use our database query wrapper properly.\n $line\n");
51 }
52 }
53 if(preg_match_all("|WHERE ([[:print:]]*)". $select[0][1] ."|U", $select[0][0], $where, PREG_SET_ORDER)) {
54 if (strstr($where[0][1], '$')) {
55 report(" - The SELECT query at line $lineno is potentially insecure as it contains a variable in the WHERE statement and does not use our database query wrapper properly.\n $line\n");
56 }
57 }
58 }
59 }
60 else if (preg_match('|["\']INSERT|', $line)) {
61 preg_match_all('|["\']INSERT INTO [[:print:]]*;|', $line, $insert, PREG_SET_ORDER);
62 if (isset($insert[0])) {
63 preg_match_all("|\(.*\)|U", $insert[0][0], $matches, PREG_SET_ORDER);
64 if (!isset($matches[0])) return; // Some nonstandard query
65 if (!isset($matches[1])) {
66 report(" - The INSERT query at line $lineno is potentially invalid.\n $line\n");
67 }
68 else {
69 $fields = count(explode(',', $matches[0][0]));
70 $arguments = count(explode(',', $matches[1][0]));
71 if ($fields !== $arguments) {
72 report(" - The INSERT query at line $lineno does not contain the same number of fields as number of arguments.\n $line\n");
73 }
74 if (strstr(implode('', $matches[1]), '$')) {
75 report(" - The INSERT query at line $lineno is potentially insecure as it does not use our database query wrapper properly.\n $line\n");
76 }
77 }
78 }
79 }
80 else if (preg_match('|["\']UPDATE|', $line)) {
81 preg_match_all('|["\']UPDATE [[:print:]]*;|', $line, $update, PREG_SET_ORDER);
82 if (isset($update[0])) {
83 if(preg_match_all("|SET ([[:print:]]*) WHERE|U", $update[0][0], $set, PREG_SET_ORDER)) {
84 if (strstr($set[0][1], '$')) {
85 report(" - The UPDATE query at line $lineno is potentially insecure as it contains a variable in the SET statement and does not use our database query wrapper properly.\n $line\n");
86 }
87 }
88 else if(preg_match_all("|SET ([[:print:]]*);|U", $update[0][0], $set, PREG_SET_ORDER)) {
89 if (strstr($set[0][1], '$')) {
90 report(" - The UPDATE query at line $lineno is potentially insecure as it contains a variable in the SET statement and does not use our database query wrapper properly.\n $line\n");
91 }
92 }
93 if(preg_match_all("|WHERE ([[:print:]]*),|U", $update[0][0], $where, PREG_SET_ORDER)) {
94 if (strstr($where[0][1], '$')) {
95 report(" - The UPDATE query at line $lineno is potentially insecure as it contains a variable in the WHERE statement and does not use our database query wrapper properly.\n $line\n");
96 }
97 }
98 }
99 }
100 else if (preg_match('|["\']DELETE|', $line)) {
101 preg_match_all('|["\']DELETE FROM [[:print:]]*;|', $line, $delete, PREG_SET_ORDER);
102 if (isset($delete[0])) {
103 if(preg_match_all("|WHERE ([[:print:]]*),|U", $delete[0][0], $where, PREG_SET_ORDER)) {
104 if (strstr($where[0][1], '$')) {
105 report(" - The DELETE query at line $lineno is potentially insecure as it contains a variable in the WHERE statement and does not use our database query wrapper properly.\n $line\n");
106 }
107 }
108 }
109 }
110 }
111
112 /**
113 * Report an error.
114 */
115 function report($message) {
116 global $argv;
117 static $fd;
118
119 if ($fd == NULL) {
120 $fd = fopen($argv[2], 'w');
121 }
122 fwrite($fd, wordwrap($message));
123 }
124
125 /**
126 * Return the $arg-th word in the line. If $arg is NULL, the last word is returned.
127 */
128 function word($line, $arg = NULL) {
129 $words = preg_split('[\s]', $line, -1, PREG_SPLIT_NO_EMPTY);
130 if (count($words)) {
131 if ($arg == -1) $arg = count($words) - 1; // -1 == last element
132 return is_null($arg) ? $words : $words[$arg];
133 }
134 return FALSE;
135 }
136
137 /**
138 * Parse a file and check its consistency.
139 */
140 function parse_file($file) {
141 global $data;
142
143 report("Checking file $file ...\n\n");
144
145 if ($lines = file($file)) {
146 for ($i = 0; $i < count($lines); $i++) {
147 check_sql_prefix($i, $lines[$i]);
148 check_camel_case($i, $lines[$i]);
149 check_else_clause($i, $lines[$i]);
150 check_db_wrapper($i, $lines[$i]);
151 }
152 }
153 }
154
155
156 function parse_directory($dir) {
157 report("Checking directory $dir ...\n\n");
158
159 $fd = opendir($dir);
160 while ($file = readdir($fd)) {
161 if (is_dir("$dir/$file") && $file != '.' && $file != '..' && $file != 'CVS') {
162 parse_directory("$dir/$file");
163 }
164 else if (strstr($file, '.module') || strstr($file, '.theme') || strstr($file, '.inc') || strstr($file, '.php')) {
165 parse_file("$dir/$file");
166 }
167 }
168 fclose($fd);
169 }
170
171 report(date('D F j, Y, G:i:s') ."\n\n");
172
173 parse_directory($argv[1]);
174
175 ?>

  ViewVC Help
Powered by ViewVC 1.1.2