'') && ($restore['extended_insert_flag'] == -1)) { if ($showErrors) { // unknown command -> output debug information v($restore); echo "
Sql: " . htmlspecialchars($complete_sql); die('
' . $lang['L_UNKNOWN_SQLCOMMAND'] . ': ' . $zeile . '

' . $complete_sql); } else return array( false, $complete_sql); } } $last_char = substr(rtrim($zeile), -1); // retain new lines - otherwise keywords are glued together // e.g. 'null' and on next line 'check' would necome 'nullcheck' $complete_sql .= $zeile . "\n"; if ($sqlparser_status == 3 || $sqlparser_status == 8) { //INSERT or REPLACE if (isCompleteQuery($complete_sql)) { $query_found = true; $complete_sql = trim($complete_sql); if (substr($complete_sql, -2) == '*/') { $complete_sql = deleteInlineComments($complete_sql); } // end of extended insert found? if (substr($complete_sql, -2) == ');') { $restore['extended_insert_flag'] = -1; } // if there is a ")," at end of line -> extended Insert-Modus -> set flag else if (substr($complete_sql, -2) == '),') { // letztes Komme gegen Semikolon tauschen $complete_sql = substr($complete_sql, 0, -1); $restore['extended_inserts'] = 1; $restore['extended_insert_flag'] = 1; } $compare = substr(strtoupper($complete_sql), 0, 7); if (($compare != 'INSERT ' && $compare != 'REPLACE')) { // we do have extended inserts here -> prepend insert syntax // if we don't have it because of a page refresh -> get it if (!isset($restore['insert_syntax'])) { $restore['insert_syntax'] = Sql::getInsertSyntax( $dbo, $restore['actual_table'] ); } $complete_sql = $restore['insert_syntax'] . ' VALUES ' . $complete_sql; } else { // remember the INSERT syntax $ipos = strpos(strtoupper($complete_sql), ' VALUES'); if (!$ipos === false) $restore['insert_syntax'] = substr($complete_sql, 0, $ipos); else { if ($sqlparser_status == 3) $restore['insert_syntax'] = 'INSERT INTO `' . $restore['actual_table'] . '`'; else $restore['insert_syntax'] = 'REPLACE INTO `' . $restore['actual_table'] . '`'; } } } } else if ($sqlparser_status == 1) { // delete action if ($last_char == ';') $query_found = true; $restore['actual_table'] = getTablename($complete_sql); } else if ($sqlparser_status == 2) { // Create-command is finished if there is a colon at the end of line if ($last_char == ';') { $restore['speed'] = $config['minspeed']; // Restore this table? $do_it = true; if (is_array($restore['tables_to_restore'])) { $do_it = false; if (in_array($restore['actual_table'], $restore['tables_to_restore'])) { $do_it = true; } else { // if we do a partial restore with selected tables and we already inserted all // of them and we now have a table we don't need to restore // -> we did all we need to do! Check and finish the process in that case // (we don't need to further walk through the file if all needed tables are done) if ($restore['table_ready'] == $restore['tables_total']) { $sqlparser_status = 0; $restore['EOB'] = true; } } } $tablename = getTablename($complete_sql); if ($do_it) { $complete_sql = getCorrectedCreateCommand($complete_sql); $restore['table_ready']++; } else $complete_sql = ''; $restore['actual_table'] = $tablename; $query_found = true; $sqlparser_status = 0; } } // Index else if ($sqlparser_status == 4) { if ($last_char == ';') { $restore['speed'] = $config['minspeed']; $complete_sql = deleteInlineComments($complete_sql); $query_found = true; } } // Comment or condition else if ($sqlparser_status == 5) { $t = strrpos($zeile, '*/;'); if (!$t === false) { $restore['speed'] = $config['minspeed']; $query_found = true; } } // multiline-comment else if ($sqlparser_status == 6) { $t = strrpos($zeile, '*/'); if (!$t === false) { $complete_sql = ''; $sqlparser_status = 0; } } // commands that mustn't be executet else if ($sqlparser_status == 7) { if ($last_char == ';') { $restore['speed'] = $config['minspeed']; $complete_sql = ''; $sqlparser_status = 0; } } if (($restore['compressed']) && (gzeof($restore['filehandle']))) $restore['fileEOF'] = true; elseif ((!$restore['compressed']) && (feof($restore['filehandle']))) $restore['fileEOF'] = true; } // if special tables are selected for restoring, check if this query belongs to them if (is_array($restore['tables_to_restore']) && !(in_array($restore['actual_table'], $restore['tables_to_restore']))) { $complete_sql = ''; } //detect if a table is finished and write log message if ($sqlparser_status != 3 && $sqlparser_status != 8 && in_array($restore['last_parser_status'], array( 3, 8))) { if (isset($restore['records_inserted_table'][$restore['actual_table']])) { $message = sprintf($lang['L_RESTORE_TABLE'], $restore['actual_table']) . ': '; $message .= sprintf($lang['L_RECORDS_INSERTED'], String::formatNumber($restore['records_inserted_table'][$restore['actual_table']])); $log->write(Log::PHP, $message); } } $restore['last_parser_status'] = $sqlparser_status; $complete_sql = trim($complete_sql); return $complete_sql; } /** * Checks SQL-Create-Query for VIEW-Syntax, substitutes the old DEFINER with the actual sql-user * and returns the corrected query. * * @param string $sql SQL-Create-Command * @return string **/ function getCorrectedCreateCommand($sql) { global $config; if (strtoupper(substr($sql, 0, 16)) == 'CREATE ALGORITHM') { // It`s a VIEW. We need to substitute the original DEFINER with the actual MySQL-User $parts = explode(' ', $sql); for ($i = 0, $count = sizeof($parts); $i < $count; $i++) { if (strtoupper(substr($parts[$i], 0, 8)) == 'DEFINER=') { global $config; $parts[$i] = 'DEFINER=`' . $config['dbuser'] . '`@`' . $config['dbhost'] . '`'; $sql = implode(' ', $parts); break; } } } return $sql; } /** * Deletes inline-comments from a SQL-String * * @param string $sql SQL-Command * * @return string $sql The cleaned SQL-String **/ function deleteInlineComments($sql) { $array = array(); preg_match_all("/(\/\*(.+)\*\/)/U", $sql, $array); if (is_array($array[0])) { $sql = trim(str_replace($array[0], '', $sql)); } //If there is only a colon left, it was a condition -> clear all if ($sql == ';') $sql = ''; return $sql; } /** * Extract the tablename from a query * * @param string $sql SQL-Command * @param string $actual_table Tablename to look for if it is known * @return string The name of the table extracted from the Query **/ function getTablename($sql, $actual_table = '') { $t = substr($sql, 0, 150); // shorten string, the tablename will be in the first 150 chars // if we find the actual table in the string we got it -> return t without any further parsing if (!false === stripos($t . '` ', $actual_table)) return $t; if (!false === stripos($t . ' ', $actual_table)) return $t; // remove all keywords until the tablename is in the front position $t = str_ireplace('DROP TABLE', '', $t); $t = str_ireplace('DROP VIEW', '', $t); $t = str_ireplace('CREATE TABLE', '', $t); $t = str_ireplace('INSERT INTO', '', $t); $t = str_ireplace('REPLACE INTO', '', $t); $t = str_ireplace('IF NOT EXISTS', '', $t); $t = str_ireplace('IF EXISTS', '', $t); if (substr(strtoupper($t), 0, 16) == 'CREATE ALGORITHM') { $pos = strpos($t, 'DEFINER VIEW '); $t = substr($t, $pos, strlen($t) - $pos); } $t = str_ireplace(';', ' ;', $t); // tricky -> insert space as delimiter $t = trim($t); // now we simply can search for the first space or ` $delimiter = substr($t, 0, 1); if ($delimiter != '`') $delimiter = ' '; $found = false; $position = 1; WHILE (!$found) { if (substr($t, $position, 1) == $delimiter) $found = true; if ($position >= strlen($t)) $found = true; $position++; } $t = substr($t, 0, $position); $t = trim(str_replace('`', '', $t)); return $t; } /** * Detect if a SQL-Command is complete * * @param string $sql String to interpret as sql * @return boolean **/ function isCompleteQuery($string) { $string = str_replace('\\\\', '', trim($string)); // trim and remove escaped backslashes $string = trim($string); $quotes = substr_count($string, '\''); $escaped_quotes = substr_count($string, '\\\''); if (($quotes - $escaped_quotes) % 2 == 0) { $compare = substr($string, -2); if ($compare == '*/') $compare = substr(deleteInlineComments($string), -2); if ($compare == ');') return true; if ($compare == '),') return true; } return false; }