LZMA-Packer will einen zu kleinen Ausgangspuffer?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Sauer-RAM
Beiträge: 326
Registriert: 13.04.2009 16:22
Computerausstattung: Lenovo ThinkPad X230t Convertible
Wohnort: Haslach i. K.

LZMA-Packer will einen zu kleinen Ausgangspuffer?

Beitrag von Sauer-RAM »

Ich meine einen Bug in dem Pack- oder UnpackMemory (weiß ich leider nicht mehr genau, aber ich meine es war unpack) entdeckt zu haben:
Daten lassen sich mit dem LZMA Algorithmus scheinbar nur entpacken, wenn der Ausgangspuffer exakt so groß oder sogar kleiner ist als die Größe der Daten nach dem Entpacken, so dass man nicht einfach präventiv einen größeren Ausgangspuffer nehmen kann.

Bei ZIP funktioniert das Entpacken nur wenn der Ausgangspuffer größer oder gleich ist, was mir logischer erscheint.
Ist das ein Bug, oder ist das so gewollt?

Gruß

Felix

PS: Ich benutze die PB-Vollversion 5.20

Verschoben von NicTheQuick von 'Bugs' nach 'Allgemein'.
"Bildung kommt vom Bildschirm und nicht vom Buch, sonst hieße es ja Buchung."
Dieter Hildebrandt
"Bildung ist Das, was übrig bleibt, wenn man alles was man in der Schule gelernt hat, vergisst. "
Albert Einstein
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8837
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: LZMA-Packer will einen zu kleinen Ausgangspuffer?

Beitrag von NicTheQuick »

Das ist wohl kaum ein Bug-Report. Lies dir dazu bitte mal durch wie man einen Bug postet.

Hier fehlt auf jeden Fall schon mal die Möglichkeit das nachzuvollziehen. Also wo ist der Code, der nicht so funktioniert, wie er soll?
Benutzeravatar
Sauer-RAM
Beiträge: 326
Registriert: 13.04.2009 16:22
Computerausstattung: Lenovo ThinkPad X230t Convertible
Wohnort: Haslach i. K.

Re: LZMA-Packer will einen zu kleinen Ausgangspuffer?

Beitrag von Sauer-RAM »

Ok, tut mir Leid... In meinem "Verbesserungseifer" habe ich die Anleitung zu spät gelesen und von selbst empfand ich einen Testcode für überflüssig. Aber nun gut.

Hier ist ein Testcode.

Code: Alles auswählen

UseZipPacker()
UseLZMAPacker()

*UngepackteDaten = AllocateMemory(100)
RandomSeed(100)                           ;Damit die Daten immer gleich sind

RandomData(*UngepackteDaten,100)          ;Daten in den Eingangspuffer

;---------------------------------------------------------------------------LZMApuffer verpacken
*LZMAUnformatiert = AllocateMemory(1000)                    ;Die gepackten Daten werden größer sein, da sich Zufallsdaten
                                                            ;nicht gut komprimieren lassen.

LZMASize = CompressMemory(*UngepackteDaten,100,*LZMAUnformatiert,1000,#PB_PackerPlugin_LZMA)

*LZMAFormatiert = AllocateMemory(LZMASize)
MoveMemory(*LZMAUnformatiert,*LZMAFormatiert,LZMASize)
;-----------------------------------------------------------------------------------------------


;---------------------------------------------------------------------------ZIPpuffer verpacken
*ZIPUnformatiert = AllocateMemory(1000)                   ;Die gepackten Daten werden größer sein, da sich Zufallsdaten
                                                          ;nicht gut komprimieren lassen.

ZIPSize = CompressMemory(*UngepackteDaten,100,*ZIPUnformatiert,1000,#PB_PackerPlugin_Zip)

*ZIPFormatiert = AllocateMemory(ZIPSize)
MoveMemory(*ZIPUnformatiert,*ZIPFormatiert,ZIPSize)
;----------------------------------------------------------------------------------------------

;-------------------------------------------------------------------------ZIP Dekomprimierung (erfolgreich)
*ZIPOutput = AllocateMemory(MemorySize(*ZIPFormatiert) * 20)    ;Da man in normalen Anwendungen die Anfangsgröße nicht kennt,
                                                                ;nimmt man einen größeren Wert an.

ZIPErgebnis = UncompressMemory(*ZIPFormatiert,ZIPSize,*ZIPOutput,MemorySize(*ZIPOutput),#PB_PackerPlugin_Zip)
If ZIPErgebnis
  Debug "ZIP war erfolgreich"
  Debug "Daten des ZIP-Decomprimierers:"
  Debug PeekS(*ZIPOutput,ZIPErgebnis)
  Debug ""
Else
  Debug "ZIP war nicht erfolgreich"
  Debug ""
EndIf
;----------------------------------------------------------------------------------------------------------

;-------------------------------------------------------------------------LZMA Dekomprimierung (nicht erfolgreich)
*LZMAOutput = AllocateMemory(MemorySize(*LZMAFormatiert) * 20)    ;Da man in normalen Anwendungen die Anfangsgröße nicht kennt,
                                                                ;nimmt man einen größeren Wert an.

LZMAErgebnis = UncompressMemory(*LZMAFormatiert,LZMASize,*LZMAOutput,MemorySize(*LZMAOutput),#PB_PackerPlugin_LZMA)
If LZMAErgebnis
  Debug "LZMA war erfolgreich"
  Debug "Daten des LZMA-Decomprimierers:"
  Debug ""
  Debug PeekS(*LZMAOutput,ZIPErgebnis)
Else
  Debug "LZMA war nicht erfolgreich. Der Puffer ist seltsamerweise ZU GROSS?!?"
  Debug ""
EndIf
;----------------------------------------------------------------------------------------------------------

;-------------------------------------------------------------------------LZMA Dekomprimierung (erfolgreich)
*LZMAOutput = AllocateMemory(MemorySize(*LZMAFormatiert) * 0.5) ;Hier nehme ich eine eindeutig zu kleinen Ausgangsgröße an

LZMAErgebnis = UncompressMemory(*LZMAFormatiert,LZMASize,*LZMAOutput,MemorySize(*LZMAOutput),#PB_PackerPlugin_LZMA)
If LZMAErgebnis
  Debug "LZMA war erfolgreich"
  Debug "Daten des LZMA-Decomprimierers:"
  Debug PeekS(*LZMAOutput,ZIPErgebnis)
  Debug ""
Else
  Debug "LZMA war nicht erfolgreich. Der Puffer ist seltsamerweise ZU GROSS?!?"
  Debug ""
EndIf
;----------------------------------------------------------------------------------------------------------

;-------------------------------------------------------------------------LZMA Dekomprimierung (erfolgreich 2)
*LZMAOutput = AllocateMemory(100) ;Hier gebe ich die exakte Ausgangsgröße an, die ich in anderen Programmen nicht kenne.

LZMAErgebnis = UncompressMemory(*LZMAFormatiert,LZMASize,*LZMAOutput,MemorySize(*LZMAOutput),#PB_PackerPlugin_LZMA)
If LZMAErgebnis
  Debug "LZMA war erfolgreich"
  Debug "Daten des LZMA-Decomprimierers:"
  Debug PeekS(*LZMAOutput,ZIPErgebnis)
  Debug ""
Else
  Debug "LZMA war nicht erfolgreich. Der Puffer ist seltsamerweise ZU GROSS?!?"
  Debug ""
EndIf
;----------------------------------------------------------------------------------------------------------
Ich habe in dem Code darauf verzichtet zu beweisen dass der ZIP-Packer bei zu kleinen Ausgangspuffern nicht funktioniert, aber ich gehe davon aus, dass dies nur logisch ist und eigentlich nicht direkt mit dem Bug zusammenhängt. Natürlich könnt ihr dies durch kleine Modifikationen des Codes selbst teste.
Desweiteren habe ich untypischerweise pseudozufällige Daten angenommen, bei denen die komprimierung der Daten größer ist als die unkomprimierten. Auch hier lässt sich durch modifikation meines Codes beweisen, dass der Effekt auch bei "realen" Daten vorkommt.

Der Code wurde mit dem Debuger, im ASCII-Modus auf einem Windoof 7 Home Premium (32 Bit) SP 1 mit der PB-Vollversion 5.20 LTS ausgeführt.

Sollte ich etwas vergessen haben, bitte ich um Rückmeldung.

Gruß

Felix
"Bildung kommt vom Bildschirm und nicht vom Buch, sonst hieße es ja Buchung."
Dieter Hildebrandt
"Bildung ist Das, was übrig bleibt, wenn man alles was man in der Schule gelernt hat, vergisst. "
Albert Einstein
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: LZMA-Packer will einen zu kleinen Ausgangspuffer?

Beitrag von ts-soft »

Wenn man die Grösse des Originals nicht kennt, macht man eindeutig was verkehrt :wink:
Jedes Archivformat (als Datei) enthält Header mit Informationen über die gepackte, ungepackte, prüfsummen usw.
Wenn man im Speicher komprimiert, erstellt man sich natürlich auch einen solchen Header, alles andere ist jedenfalls
sehr unprofessionell und mit Sicherheit kein Bug!

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Sauer-RAM
Beiträge: 326
Registriert: 13.04.2009 16:22
Computerausstattung: Lenovo ThinkPad X230t Convertible
Wohnort: Haslach i. K.

Re: LZMA-Packer will einen zu kleinen Ausgangspuffer?

Beitrag von Sauer-RAM »

In meinem Fall benutze ich die Komprimierung um die Redundanzen aus Texten zu nehmen um diese danach zu verschlüsseln und dadurch einen Statistischen Angriff zu erschweren oder du verhindern. Ich möchte auch keinerlei Hinweise auf den Inhalt der Daten in der Verschlüsselung übermitteln, also auch keine Größe. Zudem erzeugt das nur einen Unnötigen Overhead, der bei sehr kleinen Nachrichten und großer Anzahl dieser schon ins Gewicht fällt.

Ich habe mich nur gewundert, warum zu große Puffer bei dem Zip geht, bei dem LZMA nicht. Naja, dann hat sich die Sache wohl erledigt.
Wenn aber jemand eine Antwort auf meine Frage weiß, dann würde ich mich über eine Antwort freuen.

Gruß

Felix

P.S. Die Daten werden per TCP übertragen, haben also schon eine Fehlerkorrektur und dann kann ich mir meine eigene größtenteils sparen.
Und wenn ich durch einen größeren Buffer den gleichen Effekt wie durch einen größeren Overhead erreichen kann, dann wähle ich den Buffer. Ich habe genug RAM ^^. Lieber verbrat ich 0,08% mehr Rechenzeit und Arbeitsspeicher, als dass ich bei kleinen Paketen ca 7,5% mehr Daten übertragen muss.
"Bildung kommt vom Bildschirm und nicht vom Buch, sonst hieße es ja Buchung."
Dieter Hildebrandt
"Bildung ist Das, was übrig bleibt, wenn man alles was man in der Schule gelernt hat, vergisst. "
Albert Einstein
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: LZMA-Packer will einen zu kleinen Ausgangspuffer?

Beitrag von Thorium »

Die dekomprimierte Größe ist bereits Teil des LZMA Headers, wenn PB den nicht entfernt.

Von der Logik her sollte man aber auf jeden Fall in größere Puffer entpacken können. Kann schließlich sein das ich vor oder nach dem entpacken noch was in den Puffer schreiben möchte.

Etwas zu entpacken ohne die korrekte Größe zu kennen kann zum Sicherheitsproblem werden. Es darf nie in einen zu kleinen Puffer entpackt werden, so das er nicht überläuft.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
matbal
Beiträge: 261
Registriert: 30.03.2011 20:53

Re: LZMA-Packer will einen zu kleinen Ausgangspuffer?

Beitrag von matbal »

Laut PB-Hilfetext soll UncompressMemory() die Größe der dekomprimierten Daten zurückgeben.
Beim LZMA-Packer wird aber 0 zurückgegeben, obwohl richtig entpackt wurde. Für mich sieht das nach Fehler aus.

Code: Alles auswählen

EnableExplicit

UseLZMAPacker()
Define Plugin = #PB_PackerPlugin_LZMA

;UseZipPacker()
;Define Plugin = #PB_PackerPlugin_Zip


Define *Buffer1 = AllocateMemory(1000) ; Eingabe
Define *Buffer2 = AllocateMemory(1000) ; Komprimiert
Define *Buffer3 = AllocateMemory(1000) ; Unkompimiert


Define Text$ = "Das ist der zu packende Text, der viel zu groß ist"
Define InpLen = Len(Text$)
Define CmpLen
Define DecLen

PokeS(*Buffer1, Text$, InpLen, #PB_Ascii)

Debug "Text Original: " + PeekS(*Buffer1, #PB_All, #PB_Ascii)
Debug "Länge Original: " + InpLen

CmpLen = CompressMemory(*Buffer1, InpLen, *Buffer2, 1000, Plugin)
Debug "Länge komprimiert: " + CmpLen

DecLen = UncompressMemory(*Buffer2, CmpLen, *Buffer3, 1000, Plugin)
Debug "Länge dekomprimiert: " + DecLen

Debug "Text dekomprimiert: " + PeekS(*Buffer3, #PB_All, #PB_Ascii)


Benutzeravatar
Sauer-RAM
Beiträge: 326
Registriert: 13.04.2009 16:22
Computerausstattung: Lenovo ThinkPad X230t Convertible
Wohnort: Haslach i. K.

Re: LZMA-Packer will einen zu kleinen Ausgangspuffer?

Beitrag von Sauer-RAM »

Ja, du hast recht. Der LZMA entpackt zwar korrekt, bei zu großem Ausgangspuffer gibt er jedoch 0 zurück.
Das ist ein Bug. Ob es nun sinnvoll ist die Länge an die zu übermittelnden Daten anzufügen oder nicht.
Bug bleib Bug.
"Bildung kommt vom Bildschirm und nicht vom Buch, sonst hieße es ja Buchung."
Dieter Hildebrandt
"Bildung ist Das, was übrig bleibt, wenn man alles was man in der Schule gelernt hat, vergisst. "
Albert Einstein
Antworten