Stavo aggiornando il codice di un progetto da una versione 1998 di zlib a una versione 2013 di zlib. Una cosa che sembra aver cambiato è che ha usato per essere una bandiera "use_crc" sulla funzione di decompressione, che sembrava aver scomparso:Come imitare un flag "use_crc" su (hacked) 1998 uncompress() nel 2013 interfaccia zlib API?
int ZEXPORT uncompress (dest, destLen, source, sourceLen, use_crc)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
int use_crc; // <-- vanished (?)
(UPDATE: come ha sottolineato @ Joe, questo è probabilmente un third-party modification. Titolo aggiornato di conseguenza. il resto della domanda è ancora applicabile, come in "come dovrei meglio farlo con l'odierna magazzino zlib".)
nel codice che sto studiando, uncompress () viene chiamato da qualcosa che decostruisce il formato binario di un .zip e passa in un "carico utile" di dati. Il codice aveva passato il flag crc come 1. Se il flag non fosse usato, otterrebbe un Z_DATA_ERROR (-3). (Un Zlib senza flag use_crc ottiene Z_DATA_ERROR come se il flag fosse stato falso.)
In esperimenti, ho trovato che file molto piccoli funzionavano senza use_crc. Quindi i piccoli file di conteggio sono passati a non lavorare tra "123456789"
e "123456789"
. La ragione era: questo è il primo file che è stato sgonfiato invece memorizzato compresso (a quale zip chiamato un risparmio di "6%")
In dibatte con opzioni per ottenere zlib ad accettarlo, ho provato molte cose. Questo comprendeva provare il 16 + MAX_WBITS. Nulla sembrava elaborare il carico utile da zip test.zip test.txt come il vecchio codice.
Se volevo sottrarre una delle dimensioni della mia destinazione, mi sembrava di essere in grado di sopprimere il controllo errato ... alla perdita di un byte. Ecco il semplice programma di test con il minimo zip payload hardcoded:
#include <stdio.h>
#include "zlib.h"
int main(int argc, char *argv[]) {
char compressed[] = { 0x78, 0x9C, 0x33, 0x34, 0x32, 0x36, 0x31, 0x35, 0x33,
0xB7, 0xB0, 0x34, 0x30, 0x04, 0xB1, 0xB8, 0x00, 0x31, 0x30, 0xB1, 0x30,
0x10, 0x00, 0x00, 0x00 }; // last 4 bytes are size (16)
char uncompressed[16 + 1]; // account for null terminator
int ret; z_stream strm;
memset(uncompressed, 'X', 16);
uncompressed[16] = '\0';
strm.zalloc = strm.zfree = strm.opaque = Z_NULL;
strm.total_out = 0;
strm.avail_in = 25;
strm.next_in = compressed;
ret = inflateInit2(&strm, MAX_WBITS /* + 16 */); // it is Z_OK
strm.avail_out = 15; // 16 gives error -3: "incorrect header check"
strm.next_out = uncompressed;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret != /* Z_STREAM_END */ Z_OK) { // doesn't finish...
printf("inflate() error %d: %s\n", ret, strm.msg);
return 2;
}
inflateEnd(&strm);
printf("successful inflation: %s\n", uncompressed);
return 0;
}
L'output è:
inflazione successo: 123456789X
Mostrando i dati sta diventando non compressi, ma abbiamo bisogno di tutti 16 byte. (C'è una nuova riga dal file che deve essere ricevuto.) 16 + MAX_WBITS non possono nemmeno averlo.
Qualche idea cosa non va? Nessuna permutazione delle impostazioni sembra arrivare senza errori.
Quale versione di zlib è presente? Ho solo fatto qualche ricerca attraverso https://github.com/madler/zlib/blob/v1.1.1/uncompr.c e guardando le diverse versioni dei tag e non ho trovato alcun ref "use_crc'. Possibile questa è stata una patch di zlib ufficiale da parte di qualche terza parte? – Joe
@Joe Potrebbe non essere ufficiale, buon punto. È nella base di codice Rebol, che aveva un file estratto: [u-zlib.c] (https://github.com/rebol/rebol/blob/25033f897b2bd466068d7663563cd3ff64740b94/src/core/u-zlib.c#L2063). Non c'erano note sull'aggiunta, ma guardandolo su GitHub ha un tabù insolito, suggerendo che probabilmente hai ragione. Il mio vero obiettivo è quello di decodificare quel file binario, quindi aggiornerò la domanda. – HostileFork
Penso che la migliore risposta sia non provare nemmeno a portarla su uno zlib più recente. Tratta questi file come se non fossero affatto zlib (che in realtà non lo sono, dal momento che sono generati da uno zlib hackerato). Fai finta che l'unico modo per decomprimerli sia con lo stesso strumento che li ha compressi. Sei collegato al github. Decomprimi i tuoi file con rebol, salvali in un formato più ragionevole e non ripetere l'errore di usare rebol (o il suo zlib (o il suo flag use_crc)) in futuro –