kaputte Daten von serialize() - Wiederherstellung?
Julian von Mendel
- php
Hi!
Ich habe hier eine Datei mit 898393 Zeichen, die ein mit serialize() bearbeitetes Array darstellen sollen. Die Datei ist korrupt und kann mit unserialize() nicht zurück verwandelt werden. Ich habe 1h zur Wiederherstellung. Wie finde ich den Fehler (ist vermutlich nur einer)?
Schöne Grüße
Julian
Hallo Julian!
Wie finde ich den Fehler (ist vermutlich nur einer)?
Mach mal einen neuen übersichtlichen Array. serialize ihn, und schau Dir so an, wie serialize arbeitet (alternativ könntest Du auch die Sourcen von PHP anschauen, wenn Du C kannst).
Wenn Du das System einigermaßen durchschaut hast, suche nach Unregelmäßigkeiten in Deiner kaputten Datei.
So würd ich das vermutlich machen.
MfG
Götz
Hi Götz!
Wie finde ich den Fehler (ist vermutlich nur einer)?
Mach mal einen neuen übersichtlichen Array. serialize ihn, und schau Dir so an, wie serialize arbeitet (alternativ könntest Du auch die Sourcen von PHP anschauen, wenn Du C kannst).
Wenn Du das System einigermaßen durchschaut hast, suche nach Unregelmäßigkeiten in Deiner kaputten Datei.So würd ich das vermutlich machen.
Auch bei einer Datei mit 900 kb? Ich finde, für das manuelle Durchgehen ist das sehr viel, besonders bei dieser unübersichtlichen Struktur. Wie serialize arbeitet weiß ich bereits ungefähr.
Ich versuche im Moment einen Parser zu schreiben der etwas fehlertoleranter ist als diese blöde unserialize()-Funktion. Mal sehen.
Schöne Grüße
Julian
Hi!
Ich versuche im Moment einen Parser zu schreiben der etwas fehlertoleranter ist als diese blöde unserialize()-Funktion. Mal sehen.
Du kannst Dir ja angucken wie die unserialize()-Funktion arbeitet, und das mit PHP nachbauen, und an entsprechenden Stellen (wenn Du ein Problem beim Parsen bekommst) Fehler ausgeben, die Dir helfen. Aber die Stunde ist ja eh schon um...
Grüße
Andreas
Hello,
Ich versuche im Moment einen Parser zu schreiben der etwas fehlertoleranter ist als diese blöde unserialize()-Funktion. Mal sehen.
Viel Spaß dabei.
Habe ich auch schon versucht.
Serialize arbeitet mit einem sogenannten Domino-Format.
Wenn ein (entscheidenes) Zeichen fehlt, kommst Du total durcheinander.
Es ist aber in gewisser Weise Human Readable und positionsbeunden nach bestimmten Regeln.
Allerdings gibt es keine Synchronisationsmarken, wie z.B. bei CSV.
Harzliche Grüße aus http://www.annerschbarrich.de
Tom
Moin,
Ich versuche im Moment einen Parser zu schreiben der etwas fehlertoleranter ist als diese blöde unserialize()-Funktion. Mal sehen.
Viel Spaß dabei.
Habe ich auch schon versucht.
Serialize arbeitet mit einem sogenannten Domino-Format.
Wenn ein (entscheidenes) Zeichen fehlt, kommst Du total durcheinander.
Es ist aber in gewisser Weise Human Readable und positionsbeunden nach bestimmten Regeln.
Hmm? Also zumindest Syntaxfehler sollten sich recht gut automatisch lokalisieren lassen. Es ist zwar mehr-oder-weniger ein Tag-Length-Value-Format die wie du schriebst üblicherweise auf fehlende oder eingeschobene Bytes eher empfindlich reagieren, hat aber noch zusätzliche Redundanz drin, welche Plausibilitätsprüfungen erleichtert.
Wenn du etwas wie s3:"bla" hast, wo s:3:"bla" stehen müsste ist es leicht den Fehler zu finden. Ebenso kann man leicht einen Fehler bemerken wenn man s:4:"Teµst" einliest, oder a:2:{i:0;s:4:"Test";} etc. pp.
Die Fälle wo die angebene Länge von der tatsächlichen Länge soweit abweicht dass man rein zufällig wieder genau auf Metadaten landet und erst später mitkriegt, dass das keine echten Metadaten waren (sondern zum Beispiel Teile eines Postings über das serialize-Format ;-) oder man zu wenig (zu viel eher selten) Werte in einem Array hat sollten _sehr_ selten sein.
Dass man die meisten der Fehler nicht automatisch beheben kann, sondern sich ein Mensch das ansehen muß steht auf einem anderen Blatt. Aber darum geht es Julian wohl auch gar nicht soweit ich ihn verstanden habe.
Hello,
Dass man die meisten der Fehler nicht automatisch beheben kann, sondern sich ein Mensch das ansehen muß steht auf einem anderen Blatt. Aber darum geht es Julian wohl auch gar nicht soweit ich ihn verstanden habe.
Ist was wahres dran. Man könnte versuchen, eine Syntaxprüfung zu programmieren und die ausgeworfenen Fehlerstellen dann der Sichtkontrolle unterziehen. Unangenehem wird es aber, wenn Klammern fehlen und hinterher durch weitere fehlende Klammern wieder kompensiert werden. Das Gleiche gilt für Häkchen und andere Metazeichen, die auch im Datenstrom vorkommen können.
Harzliche Grüße aus http://www.annerschbarrich.de
Tom
Moin,
Ist was wahres dran. Man könnte versuchen, eine Syntaxprüfung zu programmieren und die ausgeworfenen Fehlerstellen dann der Sichtkontrolle unterziehen. Unangenehem wird es aber, wenn Klammern fehlen und hinterher durch weitere fehlende Klammern wieder kompensiert werden. Das Gleiche gilt für Häkchen und andere Metazeichen, die auch im Datenstrom vorkommen können.
Jein, das hatte ich versucht klarzumachen. Das Datenformat ist in dieser Hinsicht freundlicherweise redundant: Klammern und Anführungszeichen sind zwar als Begrenzer drin, gleichzeitig hat man aber auch eine Längenangabe (die in Implementierungen die halbwegs performant sein wollen vermutlich als primäres Kriterium dienen wird).
D.h. im Falle von Strings weiss man wie lang der String ist, liest dann soviele Zeichen ein und wenn man dann nicht _genau_ auf einem Anführungszeichen zu stehen kommt, dann hat man einen Fehler gefunden. Und wie es nach dem Anführungszeichen weiterzugehen hat ist durch die vorhergehenden Daten auch genau festgelegt.
Entsprechend mit Arrays: man weiss wieviele Elemente drin vorkommen müssen und liest so viele ein. Wenn einem zwischendurch eine überflüssige Klammer begegnet oder man nach der richtigen Zahl Elemente nicht genau auf einer Klammer landet, hat man einen Fehler gefunden.
Hello,
Jein, das hatte ich versucht klarzumachen. Das Datenformat ist in dieser Hinsicht freundlicherweise redundant:
Ja. Das kann ich nachvollzeiehen.
Ich habe da noch eine Aufgabe auf meinem Zettel stehen:
Die Formate von Serialize() und Session wechselseitig ineinander zu überführen.
Ich verstehe nämlich nicht, dass es keine hauseigene Funktion gibt, aus einem beliebigen Array eine Sessiondatei zu erzeugen und warum die Formate sich überhaupt unterscheiden.
Harzliche Grüße aus http://www.annerschbarrich.de
Tom
Hallo,
erster Teilerfolg: Der Fehler scheint in nicht maskierten Zeichen und falschen Längenangaben zu liegen. Ich weiß nicht wie mein Programm das geschafft hat eine solche Datei zu erzeugen. Aber jetzt hab ich meine Parser fast so weit dass er die Daten automatisch korrigiert. Und dannach werde ich die Software so anpassen das ein sinnvolleres Format verwendet wird.
Hat da jemand einen Tipp, wie das Datenformat am besten aufgebaut sein sollte (Mehrdimensionales sehr großes Array soll mit hoher Performance gespeichert werden)?
Schöne Grüße
Julian
Hallo,
vielen Dank für alle Tipps, jetzt gehts :)
Mein Parser korrigiert Längenangaben der Strings und maskiert Sonderzeichen. 5 Bytes waren total hinüber, die hab ich manuell rekonstruiert. Mit error_reporting(E_ALL) bekommt man angezeigt bei welchem Byte unserialize Probleme hat.
Schöne Grüße
Julian