Пример #1
0
function submit_create_action($sql)
{
    //executes a create command
    $tablename = get_tablename($sql);
    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);
                $i = $count;
            }
        }
    }
    $res = @mysqli_query($GLOBALS["___mysqli_ston"], $sql);
    if ($res === false) {
        // erster Versuch fehlgeschlagen -> zweiter Versuch - vielleicht versteht der Server die Inline-Kommentare nicht?
        $sql = del_inline_comments($sql);
        $res = @mysqli_query($GLOBALS["___mysqli_ston"], downgrade($sql));
        if ($res === false) {
            // wieder nichts. Ok, haben wir hier einen alten MySQL-Server 3.x oder 4.0.x?
            // versuchen wir es mal mit der alten Syntax
            $res = @mysqli_query($GLOBALS["___mysqli_ston"], downgrade($sql));
        }
    }
    if ($res === false) {
        // wenn wir hier angekommen sind hat nichts geklappt -> Fehler ausgeben und abbrechen
        SQLError($sql, is_object($GLOBALS["___mysqli_ston"]) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false));
        die("<br>Fatal error: Couldn't create table or view `" . $tablename . "´");
    }
    return $tablename;
}
function get_sqlbefehl()
{
    global $restore, $config, $databases, $lang;
    //Init
    $restore['fileEOF'] = false;
    $restore['EOB'] = false;
    $complete_sql = '';
    $sqlparser_status = 0;
    if (!isset($restore['eintraege_ready'])) {
        $restore['eintraege_ready'] = 0;
    }
    //Parsen
    while ($sqlparser_status != 100 && !$restore['fileEOF'] && !$restore['EOB']) {
        //nächste Zeile lesen
        $zeile = $restore['compressed'] ? gzgets($restore['filehandle']) : fgets($restore['filehandle']);
        /******************* Setzen des Parserstatus *******************/
        // herausfinden um was für einen Befehl es sich handelt
        if ($sqlparser_status == 0) {
            //Vergleichszeile, um nicht bei jedem Vergleich strtoupper ausführen zu müssen
            $zeile2 = strtoupper(trim($zeile));
            // Am Ende eines MySQLDumper-Backups angelangt?
            if (substr($zeile2, 0, 6) == '-- EOB' || substr($zeile2, 0, 5) == '# EOB') {
                $restore['EOB'] = true;
                $zeile = '--';
                $zeile2 = '--';
                $sqlparser_status = 100;
            }
            // Kommenatr?
            if (substr($zeile2, 0, 2) == '--' || substr($zeile2, 0, 1) == '#') {
                $zeile = '';
                $zeile2 = '';
                $sqlparser_status = 0;
            }
            //Einfache Anweisung finden die mit Semikolon beendet werden
            if (substr($zeile2, 0, 11) == 'LOCK TABLES') {
                $sqlparser_status = 5;
            }
            if (substr($zeile2, 0, 6) == 'COMMIT') {
                $sqlparser_status = 5;
            }
            if (substr($zeile2, 0, 5) == 'BEGIN') {
                $sqlparser_status = 5;
            }
            if (substr($zeile2, 0, 13) == 'UNLOCK TABLES') {
                $sqlparser_status = 5;
            }
            if (substr($zeile2, 0, 4) == 'SET ') {
                $sqlparser_status = 5;
            }
            if (substr($zeile2, 0, 6) == 'START ') {
                $sqlparser_status = 5;
            }
            if (substr($zeile2, 0, 3) == '/*!') {
                $sqlparser_status = 5;
            }
            //MySQL-Condition oder Kommentar
            if (substr($zeile2, 0, 12) == 'CREATE TABLE') {
                $sqlparser_status = 2;
            }
            //Createaktion
            if (substr($zeile2, 0, 12) == 'CREATE INDEX') {
                $sqlparser_status = 4;
            }
            //Indexaktion
            //Kommentar
            if ($sqlparser_status != 5 && substr($zeile2, 0, 2) == '/*') {
                $sqlparser_status = 6;
            }
            // Befehle, die nicht ausgeführt werden sollen
            if (substr($zeile2, 0, 4) == 'USE ') {
                $sqlparser_status = 7;
            }
            if (substr($zeile2, 0, 14) == 'DROP DATABASE ') {
                $sqlparser_status = 7;
            }
            if (substr($zeile2, 0, 10) == 'DROP TABLE') {
                $sqlparser_status = 1;
            }
            //Löschaktion
            if (substr($zeile2, 0, 7) == 'INSERT ') {
                $sqlparser_status = 3;
                //Datensatzaktion
                //$restore['actual_table']=strtolower(get_tablename_aus_insert($zeile));
                $restore['actual_table'] = get_tablename_aus_insert($zeile);
                // Pruefen ob die Spaltenanzahl bekannt ist und wenn nicht setzen
                if (!isset($restore['num_table_fields'][$restore['actual_table']])) {
                    $restore['num_table_fields'][$restore['actual_table']] = get_num_rows($restore['actual_table']);
                }
            }
            // Fortsetzung von erweiterten Inserts
            if ($restore['flag'] == 1) {
                $sqlparser_status = 3;
            }
            if ($sqlparser_status == 0 && trim($complete_sql) > '' && $restore['flag'] == -1) {
                // Unbekannten Befehl entdeckt
                v($restore);
                echo "<br>Sql: " . $complete_sql;
                echo "<br>Erweiterte Inserts: " . $restore['erweiterte_inserts'];
                die('<br>' . $lang['unknown_sqlcommand'] . ': ' . $zeile);
            }
            /******************* Ende von Setzen des Parserstatus *******************/
        }
        $last_char = substr(rtrim($zeile), -1);
        // Zeilenumbrüche erhalten - sonst werden Schlüsselwörter zusammengefügt
        // z.B. 'null' und in der nächsten Zeile 'check' wird zu 'nullcheck'
        $complete_sql .= $zeile . "\n";
        if ($sqlparser_status == 1) {
            //Löschaktion
            if ($last_char == ';') {
                $sqlparser_status = 100;
            }
            //Befehl komplett
        }
        if ($sqlparser_status == 2) {
            // Createanweisung ist beim Finden eines ; beendet
            if ($last_char == ';') {
                if ($config['minspeed'] > 0) {
                    $restore['anzahl_zeilen'] = $config['minspeed'];
                }
                //Spaltenanzahl fuer diese Tabelle merken
                $restore['actual_table'] = get_tablename($complete_sql);
                $complete_sql = del_inline_comments($complete_sql);
                //Inline-Kommentare entfernen
                //Create ausfuehren und Anzahl der Spalten speichern
                $restore['actual_fieldcount'] = submit_create_action($complete_sql);
                $restore['num_table_fields'][$restore['actual_table']] = $restore['actual_fieldcount'];
                // Zeile verwerfen und naechsten Befehl suchen
                $complete_sql = '';
                $sqlparser_status = 0;
            }
        }
        if ($sqlparser_status == 3) {
            //INSERT
            // Anzahl der Felder ermitteln wenn unbekannt
            if (!isset($restore['num_table_fields'][$restore['actual_table']])) {
                $restore['num_table_fields'][$restore['actual_table']] = get_num_rows($restore['actual_table']);
            }
            $AnzahlFelder = SQL_Is_Complete($complete_sql, $restore['num_table_fields'][$restore['actual_table']], DEBUG);
            // einen vollständigen Insert ermittelt
            if ($AnzahlFelder == $restore['num_table_fields'][$restore['actual_table']]) {
                $sqlparser_status = 100;
                $complete_sql = trim($complete_sql);
                // letzter Ausdruck des erweiterten Inserts erreicht?
                if (substr($complete_sql, -2) == ');') {
                    $restore['flag'] = -1;
                }
                // Wenn am Ende der Zeile ein Klammer Komma -> erweiterter Insert-Modus -> Steuerflag setzen
                if (substr($complete_sql, -2) == '),') {
                    // letztes Komme gegen Semikolon tauschen
                    $complete_sql = substr($complete_sql, 0, -1) . ';';
                    $restore['erweiterte_inserts'] = 1;
                    $restore['flag'] = 1;
                }
                if (substr($complete_sql, 0, 7) != 'INSERT ') {
                    $complete_sql = $restore['insert_syntax'] . ' VALUES ' . $complete_sql . ';';
                } else {
                    // INSERT Syntax ermitteln und merken
                    $ipos = strpos(strtoupper($complete_sql), 'VALUES');
                    if (!$ipos === false) {
                        $restore['insert_syntax'] = substr($complete_sql, 0, $ipos);
                    } else {
                        $restore['insert_syntax'] = 'INSERT INTO `' . $restore['actual_table'] . '`';
                    }
                }
                if ($AnzahlFelder > $restore['num_table_fields'][$restore['actual_table']] && $restore['erweiterte_inserts'] == 0) {
                    if (!isset($restore['table_create'][$restore['actual_table']])) {
                        global $lang;
                        include './inc/functions_sql.php';
                        $restore['table_create'][$restore['actual_table']] = GetCreateTable($databases['db_actual'], $restore['actual_table']);
                    }
                    echo '<form action="main.php?action=extinfo" method="post">';
                    echo '<p class="warnung">Parser-Fehler : zuviele gezählt in Tabelle ' . $restore["actual_table"] . ' (' . $AnzahlFelder . ' statt ' . $restore["num_table_fields"][$restore["actual_table"]] . ')';
                    echo '<br>Aktuelle Tabelle: ' . $restore['actual_table'];
                    echo '<h4>CREATE-Anweisung</h4><textarea name="create_sql" style="width:90%;height:200px;">' . $restore["table_create"][$restore["actual_table"]] . '</textarea>';
                    echo '<h4>INSERT-Anweisung</h4><textarea name="insert_sql" style="width:90%;height:200px;">' . $complete_sql . '</textarea></p><br>';
                    echo '<br><br><input type="submit" name="tell_error" value="Fehlerbericht"></form>' . $zeile;
                    die;
                }
            }
        }
        // Index
        if ($sqlparser_status == 4) {
            //Createindex
            if ($last_char == ';') {
                if ($config['minspeed'] > 0) {
                    $restore['anzahl_zeilen'] = $config['minspeed'];
                }
                $complete_sql = del_inline_comments($complete_sql);
                $sqlparser_status = 100;
                //Befehl komplett
            }
        }
        // Kommentar oder Condition
        if ($sqlparser_status == 5) {
            //Anweisung
            if ($last_char == ';') {
                if ($config['minspeed'] > 0) {
                    $restore['anzahl_zeilen'] = $config['minspeed'];
                }
                $complete_sql = del_inline_comments($complete_sql);
                $sqlparser_status = 100;
                //Befehl komplett
            }
        }
        // Mehrzeiliger oder Inline-Kommentar
        if ($sqlparser_status == 6) {
            if (!strrpos($zeile, '*/') === false) {
                $complete_sql = trim(del_inline_comments($complete_sql));
                $sqlparser_status = 0;
            }
        }
        // Befehle, die verworfen werden sollen
        if ($sqlparser_status == 7) {
            //Anweisung
            if ($last_char == ';') {
                if ($config["minspeed"] > 0) {
                    $restore["anzahl_zeilen"] = $config["minspeed"];
                }
                $complete_sql = '';
                $sqlparser_status = 0;
            }
        }
        if ($restore['compressed'] && gzeof($restore['filehandle'])) {
            $restore['fileEOF'] = true;
        }
        if (!$restore['compressed'] && feof($restore['filehandle'])) {
            $restore['fileEOF'] = true;
        }
    }
    return trim($complete_sql);
}