<?php -function do_something() +function print_hello() { echo "Hello world!\n"; } $a = 1; -do_something(); +print_hello(); $b = 2; $c = 3;
<?php function do_something() { echo "Hello world!\n"; } $a = 1; do_something(); $b = 2; +do_something(); $c = 3;
<?php function print_hello() { echo "Hello world!\n"; } $a = 1; print_hello(); $b = 2; do_something(); $c = 3;
#!/bin/sh grep do_something file.php
#!/bin/sh sed -i 's/do_something/print_hello/g' file.php
$func_prefix = "do_"; $func_name = $func_prefix . "something"; // , PHP , $func_name();
function do_something() { error_log(__FUNCTION__ . " found. Trace: " . (new Exception())); return print_hello(); }
$ ls includes/db db_tools.php index.htm mssqlnative.php oracle.php dbal.php mssql.php mysql.php postgres.php firebird.php mssql_odbc.php mysqli.php sqlite.php
$ grep -RF 'sql_query(' * | wc -l 1611
function sql_query($query = '', $cache_ttl = 0) …
$sql = 'SELECT forum_id FROM ' . TOPICS_TABLE . " WHERE topic_id = $topic_id"; $result = $db->sql_query($sql);
$sql = 'SELECT forum_id FROM ' . TOPICS_TABLE . ' WHERE topic_id = ?d'; $result = $db->sql_query_escaped($sql, $topic_id);
/** * Execute escaped SQL query * * First parameter, $query_template is the SQL template that has the following placeholders: * * ?d - value is integer * ?s - value is string (escaped by default) * ?a - array of integers for usage like IN(?a) * ?r - raw SQL (eg for use in dynamic part of SQL expression) * * Example: * * sql_query_escaped("SELECT * FROM table WHERE table_id = ?d", 42) will be executed as * * SELECT * FROM table WHERE table_id = 42 * * sql_query_escaped("SELECT * FROM table WHERE table_id IN(?a)", array(1, 2, 3)) will be executed as * * SELECT * FROM table WHERE table_id IN(1, 2, 3) * */ function sql_query_escaped($query_template) { $values = func_get_args(); array_shift($values); $regexp = '/\\?[dsar]/s'; preg_match_all($regexp, $query_template, $matches); foreach ($matches[0] as $i => $m) { if ($m == '?d') $values[$i] = intval($values[$i]); else if ($m == '?s') $values[$i] = "'" . $this->sql_escape($values[$i]) . "'"; else if ($m == '?a') $values[$i] = implode(',', array_map('intval', $values[$i])); } $idx = 0; $replace_func = function($placeholder) use ($values, &$idx) { $placeholder = $placeholder[0]; return $values[$idx++]; }; $query = preg_replace_callback($regexp, $replace_func, $query_template); return $this->sql_query($query); }
--- a/includes/db/mysqli.php +++ b/includes/db/mysqli.php @@ -151,6 +151,8 @@ class dbal_mysqli extends dbal return true; } + var $queries = array(); + /** * Base query method * @@ -162,6 +164,7 @@ class dbal_mysqli extends dbal */ function sql_query($query = '', $cache_ttl = 0) { + $this->queries[] = $query; if ($query != '') { global $cache; --- a/includes/functions.php +++ b/includes/functions.php @@ -4735,6 +4735,10 @@ function page_footer($run_cron = true) } $debug_output .= ' | <a href="' . build_url() . '&explain=1">Explain</a>'; + + foreach ($db->queries as $query) { + $debug_output .= "<pre style='text-align: left; margin-bottom: 10px;'>" . htmlspecialchars($query) . "</pre>\n<hr/>\n"; + } } }
$ grep -RF 'sql_query(' * | less
$ grep -RF 'sql_query(' * | grep -vF '$db->sql_query('
<?php // , : $files = exec('grep -RF \'$db->sql_query(\' * | awk -F: \'{print $1;}\'', $out, $retval); if ($retval) exit(1); // replacer/ $excludes = array('includes/db/', 'replacer/'); $num_lines = 0; foreach (array_unique($out) as $filename) { foreach ($excludes as $excl) { if (strpos($filename, $excl) === 0) continue(2); } $contents = file_get_contents($filename); if ($contents === false) exit(1); $lines = explode("\n", $contents); // $tokens = token_get_all($contents); $num = count($tokens); $line = 1; $type = $text = ''; // 5 : '$db', '->', 'sql_query', '(' // «» $accepted_value_types = array(T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE, '"'); foreach ($tokens as $cur_idx => $tok) { parse_token($tok, $type, $text, $line); // , 5 if ($cur_idx >= $num - 5) continue; $ln = $line; $i = $cur_idx + 1; // (http://php.net/manual/tokens.php) if ($type !== T_VARIABLE || $text !== '$db') continue; parse_token($tokens[$i++], $type, $text, $ln); if ($type !== T_OBJECT_OPERATOR || $text !== '->') continue; parse_token($tokens[$i++], $type, $text, $ln); if ($type !== T_STRING || $text !== 'sql_query') continue; parse_token($tokens[$i++], $type, $text, $ln); if ($type !== '(') continue; parse_token($tokens[$i++], $type, $text, $ln); if (!in_array($type, $accepted_value_types, true)) continue; // : , $depth = 1; $query = ''; for ($i = $i - 1; $i < $num; $i++) { parse_token($tokens[$i], $type, $text, $ln); if ($type === '(') $depth++; else if ($type === ')') $depth--; if ($depth == 0) break; $query .= $text; } $query = preg_replace(array("/[\t ]+/s", '/^/m'), array(' ', ' '), $query); $results[$filename][] = $query; $num_lines++; } } foreach ($results as $filename => $list) { echo "$filename\n"; foreach ($list as $row) echo "$row\n"; echo "\n"; } echo "Total lines recognized: $num_lines\n"; // . token_get_all function parse_token($tok, &$type, &$text, &$line) { if (is_array($tok)) list($type, $text, $line) = $tok; else $type = $text = $tok; }
includes/acp/acp_attachments.php 'INSERT INTO ' . EXTENSIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary) includes/acp/acp_bbcodes.php 'INSERT INTO ' . BBCODES_TABLE . $db->sql_build_array('INSERT', $sql_ary)
$ grep -A 5 -B 5 -RF '$db->sql_query($sql' * | less
$sql = '...'; // $db->sql_query($sql);
<?php // , $files = exec('grep -RF \'$db->sql_query($sql\' * | awk -F: \'{print $1;}\'', $out, $retval); if ($retval) exit(1); // replacer/ $excludes = array('includes/db/', 'replacer/'); $num_lines = 0; foreach (array_unique($out) as $filename) { foreach ($excludes as $excl) { if (strpos($filename, $excl) === 0) continue(2); } echo "$filename\n"; $contents = file_get_contents($filename); if ($contents === false) exit(1); $lines = explode("\n", $contents); // $tokens = token_get_all($contents); $num = count($tokens); $line = 1; $type = $text = ''; // 5 : '$db', '->', 'sql_query', '(' '$sql' foreach ($tokens as $cur_idx => $tok) { parse_token($tok, $type, $text, $line); // , 5 if ($cur_idx >= $num - 5) continue; $ln = $line; $i = $cur_idx + 1; // (http://php.net/manual/tokens.php) if ($type !== T_VARIABLE || $text !== '$db') continue; parse_token($tokens[$i++], $type, $text, $ln); if ($type !== T_OBJECT_OPERATOR || $text !== '->') continue; parse_token($tokens[$i++], $type, $text, $ln); if ($type !== T_STRING || $text !== 'sql_query') continue; parse_token($tokens[$i++], $type, $text, $ln); if ($type !== '(') continue; parse_token($tokens[$i++], $type, $text, $ln); if ($type !== T_VARIABLE || $text !== '$sql') continue; // . grep printf("%6d %s\n", $line, ltrim($lines[$line - 1])); $positions = find_dollar_sql_assignment($tokens, $cur_idx); if (!is_array($positions)) { echo " $positions\n\n"; continue; } $query = ''; for ($i = $positions['begin']; $i <= $positions['end']; $i++) { parse_token($tokens[$i], $type, $text, $ln); $query .= $text; } $query = preg_replace(array("/[\t ]+/s", '/^/m'), array(' ', ' '), $query); echo "\n" . $query . "\n\n"; $num_lines++; } echo "\n"; } echo "Total lines recognized: $num_lines\n"; // . token_get_all function parse_token($tok, &$type, &$text, &$line) { if (is_array($tok)) list($type, $text, $line) = $tok; else $type = $text = $tok; } // $sql = '...'; $db->sql_query($sql function find_dollar_sql_assignment($tokens, $db_idx) { $depth = 0; $line = 1; $type = $text = ''; // $sql for ($idx = $db_idx - 1; $idx > 0; $idx--) { parse_token($tokens[$idx], $type, $text, $line); // if ($type === ')') $depth++; else if ($type === '(') $depth--; if ($depth < 0) { return "depth < 0 on line " . __LINE__; } /* , : if (...) { $sql = 'SELECT * FROM Table1 WHERE user_id = $user_id'; } else { $sql = 'SELECT * FROM Table2'; } $result = $db->sql_query($sql); */ if ($type === '{' || $type === '}') { return "open/close brace found on line " . __LINE__; } if ($type === T_VARIABLE && $text === '$sql') { $i = $idx + 1; parse_token($tokens[$i++], $type, $text, $line); if ($type === T_WHITESPACE) parse_token($tokens[$i++], $type, $text, $line); if ($type !== '=') continue; // "$sql = " ! $begin_pos = $i; break; } } // «$sql = », // , «;» $depth = 0; for ($idx = $begin_pos; $idx < $db_idx; $idx++) { parse_token($tokens[$idx], $type, $text, $line); if ($type === '(') $depth++; else if ($type === ')') $depth--; if ($depth < 0) { return "depth < 0 on line " . __LINE__; } if ($depth === 0 && $type === ';') { return array('begin' => $begin_pos, 'end' => $idx - 1); } } // , $db->sql_query «;» // , return "Statement does not terminate on line " . __LINE__; }
cron.php 59 $db->sql_query($sql); 'UPDATE ' . CONFIG_TABLE . " SET config_value = '" . $db->sql_escape(CRON_ID) . "' WHERE config_name = 'cron_lock' AND config_value = '" . $db->sql_escape($config['cron_lock']) . "'" … includes/acp/acp_forums.php 243 $result = $db->sql_query($sql); 'SELECT * FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id" ... 1096 $db->sql_query($sql); 'DELETE FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_ids) includes/acp/acp_reasons.php ... 96 $result = $db->sql_query($sql); 'SELECT reason_id FROM ' . REPORTS_REASONS_TABLE . " WHERE reason_title = '" . $db->sql_escape($reason_row['reason_title']) . "'" ... includes/acp/acp_search.php 320 $result = $db->sql_query($sql); 'SELECT post_id, poster_id, forum_id FROM ' . POSTS_TABLE . ' WHERE post_id >= ' . (int) ($post_counter + 1) . ' AND post_id <= ' . (int) ($post_counter + $this->batch_size)
$sql = /* */ 'SELECT user_id, author_id FROM ' . PRIVMSGS_TO_TABLE . ' WHERE msg_id = ' . $attachment['post_msg_id'] /* */; $result = $db->sql_query($sql); // $sql = 'SELECT user_id, author_id FROM ' . PRIVMSGS_TO_TABLE . ' WHERE msg_id = ?d'; $result = $db->sql_query_escaped($sql, $attachment['post_msg_id']);
function rewrite_tokens($in_tokens) { static $string_types = array(T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE, '"'); $type = $text = null; $line = 1; // , , , , : // ($action == 'add') ? 'INSERT INTO ' . EXTENSION_GROUPS_TABLE . ' ' : 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' SET ' parse_token($in_tokens[0], $type, $text, $line); if ($type === T_WHITESPACE) parse_token($in_tokens[1], $type, $text, $line); if (!in_array($type, $string_types, true)) return "Expected first token to be string (got $type)"; $out_params = $out_tokens = array(); // , : // // 'SELECT * FROM ' . TABLE_SOMETHING . ' WHERE lang_id = ' . intval($lang_id) // // // // array(array('SELECT * FROM ', TABLE_SOMETHING), array(' WHERE lang_id = ', intval($lang_id))) // // , , $state = 'begin'; $left_tokens = $right_tokens = $groups = array(); $depth = 0; // foreach ($in_tokens as $tok) { parse_token($tok, $type, $text, $line); if ($type === '(') $depth++; else if ($type === ')') $depth--; if ($depth < 0) return "Brace depth less than zero"; if ($state == 'begin') { // «» , if ($depth > 0 || $type !== '.') { $left_tokens[] = $tok; } else { $state = 'end'; } } else { // , $groups if ($depth > 0 || $type !== '.') { $right_tokens[] = $tok; } else { $state = 'begin'; $groups[] = array($left_tokens, $right_tokens); $left_tokens = $right_tokens = array(); } } } // - , if (count($left_tokens)) $groups[] = array($left_tokens, $right_tokens); foreach ($groups as $grp) { list($left_tokens, $right_tokens) = $grp; // , parse_token($left_tokens[0], $type, $text, $line); if ($type === T_WHITESPACE) parse_token($left_tokens[1], $type, $text, $line); if (!in_array($type, $string_types, true)) return "first token in a group is not string"; // , foreach ($left_tokens as $tok) { parse_token($left_tokens[0], $type, $text, $line); $out_tokens[] = $tok; } if (!count($right_tokens)) break; $out_tokens[] = '.'; // - *_TABLE, , $param = tokens_to_string($right_tokens); if (preg_match('/^\\s*([A-Z0-9_]+)_TABLE\\s*$/s', $param)) { foreach ($right_tokens as $tok) $out_tokens[] = $tok; } else { // '?r', «» $out_tokens[] = array(T_CONSTANT_ENCAPSED_STRING, "'?r'", $line); $out_params[] = $param; } $out_tokens[] = '.'; } // , // , syntax error parse_token(end($out_tokens), $type, $text, $line); if ($type === '.') array_pop($out_tokens); return array( 'tokens' => $out_tokens, 'params' => $out_params, ); } function tokens_to_string($tokens) { $str = ''; $type = $text = null; $line = 1; foreach ($tokens as $tok) { parse_token($tok, $type, $text, $line); $str .= $text; } $str = preg_replace(array("/[\t ]+/s", '/^/m'), array(' ', ' '), $str); return $str; }
$sql = 'UPDATE ' . CONFIG_TABLE . " SET config_value = '" .'?r'. "' WHERE config_name = 'cron_lock' AND config_value = '" .'?r'. "'"; $db->sql_query_escaped($sql, $db->sql_escape(CRON_ID), $db->sql_escape($config['cron_lock']));
$sql = 'UPDATE ' . CONFIG_TABLE . " - SET config_value = '" . $db->sql_escape(CRON_ID) . "' - WHERE config_name = 'cron_lock' AND config_value = '" . $db->sql_escape($config['cron_lock']) . "'"; -$db->sql_query($sql); + SET config_value = '" .'?r'. "' + WHERE config_name = 'cron_lock' AND config_value = '" .'?r'. "'"; +$db->sql_query_escaped($sql, $db->sql_escape(CRON_ID), $db->sql_escape($config['cron_lock']));
- $db->sql_query('UPDATE ' . CONFIG_TABLE . ' SET config_value = ' . $sql_update . " WHERE config_name = '" . $db->sql_escape($config_name) . "'"); + $db->sql_query_escaped('UPDATE ' . CONFIG_TABLE . ' SET config_value = ' .'?r'. " WHERE config_name = '" .'?r'. "'", $sql_update, $db->sql_escape($config_name));
$ grep -RF 'sql_query(' * | wc -l 335
"... '?r' ..."
, "... ?s ..."
;Source: https://habr.com/ru/post/167337/
All Articles