Advertisement
Guest User

replacer/direct_sql.php

a guest
Jan 21st, 2013
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 3.49 KB | None | 0 0
  1. <?php
  2. require(__DIR__ . '/rewrite.php');
  3.  
  4. // Для начала, оставим только те файлы, которые содержат паттерн, который мы собираемся заменять
  5. $files = exec('grep -RF \'$db->sql_query(\' * | awk -F: \'{print $1;}\'', $out, $retval);
  6. if ($retval) exit(1);
  7.  
  8. // Наш скрипт будет жить в папке replacer/
  9. $excludes = array('includes/db/', 'replacer/');
  10.  
  11. $num_lines = 0;
  12.  
  13. foreach (array_unique($out) as $filename) {
  14.     foreach ($excludes as $excl) {
  15.         if (strpos($filename, $excl) === 0) continue(2);
  16.     }
  17.  
  18.     $contents = file_get_contents($filename);
  19.     if ($contents === false) exit(1);
  20.  
  21.     echo "$filename\n";
  22.    
  23.     $lines = explode("\n", $contents);
  24.  
  25.     // Получаем массив всех токенов в файле
  26.     $tokens = token_get_all($contents);
  27.     $num = count($tokens);
  28.     $line = 1;
  29.     $type = $text = '';
  30.  
  31.     // Нам нужно найти 5 идущих подряд токенов: '$db', '->', 'sql_query', '(' и начало запроса
  32.     // Сам запрос должен начинаться с токена с типом «строка»
  33.     $accepted_value_types = array(T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE, '"');
  34.  
  35.     $result_tokens = $tokens;
  36.    
  37.     foreach ($tokens as $cur_idx => $tok) {
  38.         parse_token($tok, $type, $text, $line);
  39.  
  40.         // Пропускаем токены в самом конце, где точно не могут уместиться наши 5 токенов
  41.         if ($cur_idx >= $num - 5) continue;
  42.        
  43.         $ln = $line;
  44.         $i = $cur_idx + 1;
  45.  
  46.         // Список токенов доступен в документации (http://php.net/manual/tokens.php)
  47.         if ($type !== T_VARIABLE || $text !== '$db') continue;
  48.         parse_token($tokens[$i++], $type, $text, $ln);
  49.         if ($type !== T_OBJECT_OPERATOR || $text !== '->') continue;
  50.         parse_token($tokens[$i++], $type, $text, $ln);
  51.         if ($type !== T_STRING || $text !== 'sql_query') continue;
  52.         $sql_query_idx = $i - 1;
  53.         parse_token($tokens[$i++], $type, $text, $ln);
  54.         if ($type !== '(') continue;
  55.         parse_token($tokens[$i++], $type, $text, $ln);
  56.         if (!in_array($type, $accepted_value_types, true)) continue;
  57.         $query_idx = $i - 1;
  58.  
  59.         // Теперь получим весь запрос: нам нужно всё до закрывающей скобки
  60.         $depth = 1;
  61.         $query = '';
  62.        
  63.         $query_tokens = array();
  64.         for ($i = $query_idx; $i < $num; $i++) {
  65.             parse_token($tokens[$i], $type, $text, $ln);
  66.             if ($type === '(') $depth++;
  67.             else if ($type === ')') $depth--;
  68.             if ($depth == 0) break;
  69.  
  70.             $query_tokens[] = $tokens[$i];
  71.         }
  72.         $last_token_idx = $i - 1;
  73.  
  74.         $rewrite_result = rewrite_tokens($query_tokens);
  75.         if (!is_array($rewrite_result)) {
  76.             echo "       Error: $rewrite_result\n";
  77.         } else {
  78.             for ($i = $query_idx; $i <= $last_token_idx; $i++) {
  79.                 parse_token($tokens[$i], $type, $text, $ln);
  80.                 if ($i > $query_idx) unset($result_tokens[$i]);
  81.             }
  82.  
  83.             $result_tokens[$sql_query_idx] = 'sql_query_escaped';
  84.             $result_tokens[$query_idx] = tokens_to_string($rewrite_result['tokens'], true);
  85.             foreach ($rewrite_result['params'] as $par) $result_tokens[$query_idx] .= ', ' . trim($par);
  86.  
  87.             $num_lines++;
  88.         }
  89.     }
  90.  
  91.     file_put_contents($filename, tokens_to_string($result_tokens, true));
  92.  
  93.     exec("php -l " . escapeshellarg($filename), $out, $retval);
  94.     if ($retval) {
  95.         fwrite(STDERR, "PHP Syntax error in $filename\n");
  96.         exit(1);
  97.     }
  98. }
  99.  
  100. echo "Total lines recognized: $num_lines\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement