«La cartella compressa non è valida»: cosa fa davvero Windows con gli archivi ZIP

Pubblicato il 12 August 2026 Aggiornato il 12 August 2026 8 visualizzazioni

La cartella compressa non è validaEsiste una frase che chiunque lavori con i file ha incontrato almeno una volta: «La cartella compressa (zippata) non è valida». Windows la pronuncia con la sicurezza di chi ha appena diagnosticato un file corrotto. Quasi sempre non è vero: lo stesso archivio, aperto con 7-Zip trenta secondi dopo, si estrae senza una protesta. Per capire cosa succeda davvero ho smesso di leggere quello che si racconta in giro e ho costruito un banco di prova: diciannove archivi ZIP validi, ciascuno costruito per isolare una sola caratteristica del formato, passati a cinque motori di estrazione diversi sulla stessa macchina, nella stessa sessione. Il risultato più interessante è che quella frase, su diciannove archivi, è comparsa una volta sola — e ha una causa specifica, misurabile al singolo carattere.

Come è stato costruito il banco di prova

Gli archivi sono stati generati su macOS con Python, verificati uno per uno con 7-Zip e Info-ZIP prima della spedizione, e trasferiti su Windows con controllo SHA-256 all'arrivo e alla fine delle prove: diciannove hash su diciannove corrispondenti, nessun file alterato dal trasferimento. È una precauzione che sembra pedante e invece è il fondamento di tutto il ragionamento, perché senza di essa qualunque errore osservato potrebbe essere l'artefatto di una copia andata storta anziché il fenomeno da studiare.

Ogni archivio isola una singola variabile. Uno ha i nomi in UTF-8 con il bit 11 del General Purpose Bit Flag correttamente impostato, il suo gemello ha gli stessi identici nomi con quel bit azzerato. Uno ha il Data Descriptor preceduto dalla firma 0x08074b50, il gemello ce l'ha senza. Uno è cifrato con AES-256, il gemello con il vecchio ZipCrypto. Le coppie servono a questo: se il gemello «corretto» si apre e l'altro no, la causa è dimostrata invece che ipotizzata, perché fra i due file non c'è nessun'altra differenza. Gli altri archivi coprono i metodi di compressione 9, 12 e 14, i percorsi lunghi, i caratteri riservati da Windows NT, i nomi di device DOS, i prefissi POSIX, i collegamenti simbolici, ventimila entry minute, le strutture ZIP64 e un nome codificato in CP437 secondo la norma legacy.

I motori messi a confronto sono cinque, e tenerli distinti è essenziale perché non sono affatto la stessa cosa. C'è zipfldr.dll, che è il codice che gira quando si fa doppio clic in Esplora file, ed è l'imputato. C'è Expand-Archive di PowerShell, che si appoggia a System.IO.Compression di .NET: motore diverso, stessa azienda. C'è tar.exe, cioè il porting di bsdtar/libarchive incluso in Windows da anni. C'è 7-Zip come termine di paragone. E c'è Python zipfile, che è anche il motore con cui il banco è stato costruito.

La macchina di prova è un Windows 11 Pro 25H2, build 26200.8875, in italiano, con code page ANSI 1252 e OEM 850, LongPathsEnabled impostato a 1 e 7-Zip 24.08 installato. Tutto quello che segue vale per questa build: dove i miei risultati contraddicono fonti pubbliche, la contraddizione va letta come «qui, oggi, non accade», non come «non è mai accaduto».

La frase, e la sua unica causa

Su diciannove archivi, il messaggio «La cartella compressa … non è valida» è comparso soltanto sull'archivio che contiene un percorso interno di 361 caratteri. Nello stesso momento, sulla stessa macchina, quell'archivio è stato estratto per intero da Expand-Archive, da tar e da 7-Zip. L'archivio è valido; è la finestra a dire il falso.

La cartella compressa non è valida
L'unica comparsa della frase in tutto il banco di prova. L'archivio che Windows dichiara non valido viene estratto per intero, nella stessa sessione, da tre motori su quattro.

A quel punto la domanda diventa una sola: dove passa esattamente la linea. L'ho cercata con archivi-sonda contenenti una sola entry di lunghezza crescente, procedendo per bisezione e confermando ogni valore sia via COM sia con il doppio clic davanti allo schermo. La risposta è netta al singolo carattere.

Lunghezza del nome dell'entry Cosa fa Esplora file Elementi enumerati
fino a 256 caratteri si apre, contenuto visibile, estrazione riuscita 1
da 257 a 259 caratteri si apre e appare vuoto, nessun errore, nessun avviso 0
260 caratteri e oltre «Impossibile aprire la cartella. La cartella compressa … non è valida.» 0

I due numeri non sono casuali. Duecentosessanta è MAX_PATH, la costante definita in windef.h che da trent'anni fissa la lunghezza massima di un percorso nelle API Win32. Duecentocinquantasei è MAX_PATH meno tre caratteri di radice — la lettera di unità, i due punti e la barra rovesciata — meno il terminatore nullo. In altre parole zipfldr.dll applica il limite al nome dell'entry preso da solo, come se dovesse comporre un percorso assoluto a partire dalla radice di un disco, indipendentemente da dove l'archivio si trovi e da dove l'utente stia estraendo.

Che sia davvero così l'ho verificato togliendo le variabili una alla volta. Ho copiato l'archivio in C:\zt, un percorso di dodici caratteri, il più corto praticamente possibile su un disco Windows: stesso rifiuto. Ho provato la stessa sonda con lo ZIP dentro una cartella da 186 caratteri e dentro una da poche decine: soglia identica. Ho verificato che LongPathsEnabled a 1 — attivo su questa macchina — non sposti il limite di un solo carattere, mentre nella stessa sessione Expand-Archive e tar ne approfittano ed estraggono senza difficoltà. Il supporto ai percorsi lunghi è attivo a livello di sistema; l'estensione dello spazio dei nomi di Esplora file non lo usa.

La fascia dei tre caratteri fra 257 e 259 merita una riga a parte, perché è la cosa peggiore emersa da tutto il banco. Lì Windows apre l'archivio, non segnala niente e mostra una cartella vuota. Tre caratteri su duecentosessanta: bisogna caderci dentro per caso, ed è probabilmente il motivo per cui non risulta documentata da nessuna parte. Chi ci finisce non ha nessun indizio che i suoi file esistano.

Una sola entry avvelena l'intero archivio

La scoperta che rende il fenomeno pericoloso nel mondo reale è che la perdita non è proporzionale. Ho costruito una sonda con tre entry corte e legittime più una sola entry da trecento caratteri: il risultato non è «tre file su quattro», è zero elementi e archivio dichiarato non valido. Le tre entry sane spariscono insieme a quella lunga. È tutto o niente.

Il caso reale che mi ha portato su questa strada lo dimostra meglio di qualunque sonda. Due archivi BagIt di acquisizione forense, prodotti dallo stesso strumento e conservati nella stessa cartella: uno si apre normalmente, l'altro viene respinto. Entrambi superano il test di integrità di 7-Zip, nessuno dei due contiene caratteri non ASCII, nessuno contiene caratteri illeciti, entrambi usano la barra come separatore secondo l'APPNOTE. L'unica variabile che li separa è la lunghezza dei percorsi interni: l'entry più lunga del primo misura 167 caratteri, quella del secondo 282. Nel secondo archivio le entry oltre soglia sono quarantaquattro su settecentonovantaquattro, il cinque e mezzo per cento — e rendono inaccessibili le altre settecentocinquanta, perfettamente valide, senza che nulla indichi quali file siano il problema.

Chiunque produca acquisizioni web dovrebbe fermarsi su questo punto. Uno strumento che trasformi un URL lungo nel nome di un file supera i 256 caratteri senza accorgersene — nell'archivio incriminato l'ultimo segmento di percorso ne misura 189 — e consegna al cliente un archivio che resta perfettamente valido per chiunque altro ma che Esplora file dichiara corrotto. In un contesto in cui l'integrità del reperto è tutto, una diagnosi sbagliata del sistema operativo è un problema serio.

Perché la diagnosi è sempre sbagliata

Il resto del banco spiega perché Windows, nei casi in cui fallisce, non riesca quasi mai a dire il vero motivo. La chiave sta in una parola che compare in tutte le finestre di errore in estrazione: «Impossibile copiare il file». Mai «estrarre». Non è una sciatteria di traduzione, è la descrizione esatta di quello che sta accadendo.

Il supporto ZIP di Windows, comparso con il pacchetto Microsoft Plus! per Windows 98 e integrato stabilmente a partire da Windows Me, non è un'applicazione di decompressione: è zipfldr.dll, un'estensione dello spazio dei nomi della shell che si aggancia a explorer.exe via COM e presenta l'archivio come se fosse una directory del file system. Per la shell, estrarre non significa decomprimere: significa copiare da una cartella finta a una cartella vera. Le entry ZIP vengono quindi mappate sulla semantica Win32 prima di essere decodificate, e tutto ciò che il formato ZIP ammette ma Win32 non sa rappresentare — un nome lungo, un carattere riservato, un collegamento simbolico, un prefisso POSIX — viene perso o rifiutato a monte, indipendentemente dalla validità dell'archivio. Quando poi qualcosa fallisce, l'errore risale dallo strato di copia, che di ZIP non sa assolutamente nulla e non ha il vocabolario per spiegare il problema.

Le conseguenze si vedono a occhio nudo. L'archivio con il metodo di compressione 12 (BZip2) si apre regolarmente, l'entry è visibile e correttamente elencata, e l'estrazione fallisce con Errore 0x80004005: Errore non specificato, che è E_FAIL, l'errore COM più generico che esista. L'archivio con il metodo 14 (LZMA) produce la stessa identica finestra, lo stesso titolo, lo stesso codice. E l'archivio cifrato con AES-256 pure: stessa finestra, stesso 0x80004005, e soprattutto nessun prompt della password, mai comparso. Tre cause tecniche completamente diverse — due algoritmi di compressione e uno schema crittografico — collassano in un unico codice che non ne nomina nessuna. Le parole «bzip2», «LZMA», «AES», «compressione» e «cifratura» non compaiono da nessuna parte.

Azione interrotta: Impossibile copiare il file, Errore 0x80004005 Errore non specificato.
Metodo di compressione 12 (BZip2). La finestra identica, con lo stesso codice, compare anche per LZMA e per AES-256: tre cause tecniche diverse, un solo 0x80004005. Si noti la dimensione dichiarata, 7,81 KB, che corrisponde al byte agli 8000 byte reali del file.

Non tutti i codici sono generici, e il confronto lo rende evidente. L'archivio che contiene nomi con i caratteri riservati da Windows NT — i due punti, l'asterisco, la barra verticale — fallisce con Errore 0x80070057: Parametro non corretto, che è ERROR_INVALID_PARAMETER mappato in HRESULT, e per una volta il nome dell'errore è pertinente: il parametro non valido è proprio il nome del file. Anche lì, però, l'esito è strano più che netto: dei nove file dell'archivio ne arrivano sul disco due, mentre tar ne estrae nove su nove sanitizzando i nomi e Expand-Archive zero su nove. E il file su cui la finestra protesta, due:punti.txt, è proprio uno dei due che vengono estratti, con il nome correttamente sanitizzato in due_punti.txt. La shell sa sanitizzare i nomi illeciti e in almeno un caso lo fa, ma non lo fa in modo sistematico, e l'errore che mostra riguarda il file che invece è riuscito.

Azione interrotta con Errore 0x80070057 Parametro non corretto sul file due:punti.txt.
Caratteri riservati da Windows NT: qui il codice è pertinente, ma l'archivio perde sette file su nove. La casella «Esegui questa operazione per tutti gli elementi correnti» è rimasta deselezionata durante la prova.

Il dettaglio che rende la cosa quasi comica è che la shell, in quelle stesse finestre, dimostra di aver letto tutto perfettamente. Dichiara Dimensione – 7,81 KB per un file che decompresso misura esattamente 8000 byte, cioè 7,8125 KB: coincide al byte. Sull'archivio AES dichiara Dimensione – 41 byte, e il contenuto in chiaro è di 41 byte esatti. Nome, tipo, data di modifica e dimensione decompressa sono sempre corretti, perché la Central Directory viene letta senza sbagliare un bit. Non è un problema di lettura dell'archivio: è un problema di decodifica del payload, e di come viene raccontato.

Che il difetto sia nella diagnostica e non nella lettura lo conferma il confronto fra i due archivi cifrati. Stesso contenuto byte per byte, stesso nome di entry, stessa sessione: quello con ZipCrypto fa comparire regolarmente il prompt della password ed estrae un file il cui SHA-256 coincide con quello prodotto da 7-Zip; quello con AES-256 non chiede niente e fallisce con il codice generico. La shell sa di avere davanti un'entry cifrata — la mostra, la misura, ne dichiara il tipo — e invece di dire «cifratura non supportata», o almeno di chiedere la password come fa due secondi dopo sull'altro archivio, usa lo stesso errore che usa per BZip2.

Esiste poi una seconda famiglia di finestre, che è bene non confondere con la prima. Quando si fa doppio clic su un file dentro l'archivio per guardarlo in anteprima, il fallimento produce una finestra intitolata Errore di Cartelle compresse che recita «Impossibile completare l'estrazione. Impossibile creare il file di destinazione.», e questa volta senza alcun codice. Il testo tradisce il meccanismo: per mostrare in anteprima un file contenuto in uno ZIP la shell lo estrae prima in una cartella temporanea, e a fallire è proprio la creazione di quel file temporaneo. Il punto rilevante è che le finestre prive di codice — il rifiuto totale dell'archivio e il fallimento dell'anteprima — sono proprio quelle di zipfldr stesso, mentre quelle con il codice arrivano dallo strato di copia. I fallimenti più gravi sono quelli su cui Windows non fornisce alcun numero da cercare su un motore di ricerca.

Finestra Errore di Cartelle compresse: Impossibile completare l'estrazione, impossibile creare il file di destinazione.
La seconda famiglia di finestre, senza alcun codice. Compare facendo doppio clic su un file dentro l'archivio: la parola «estrazione» tradisce che l'anteprima passa da una copia temporanea su disco.

La faccenda dei nomi, che non è come viene raccontata

Il caso più diffuso in assoluto riguarda la codifica dei nomi. Storicamente i nomi dei file negli archivi ZIP dovevano essere codificati in CP437, la code page del DOS; l'appendice D delle specifiche PKWARE, dalla versione 6.3.0, ha introdotto Unicode stabilendo che se il bit 11 del General Purpose Bit Flag vale 1 il nome va interpretato come UTF-8, altrimenti si ricade sulla codifica legacy. Innumerevoli librerie di terze parti scrivono nomi UTF-8 dimenticando di alzare quel bit, e da lì nascono i nomi illeggibili.

La coppia di archivi che isola questo caso è la prova più pulita del banco. Stesso contenuto, stesse dimensioni, stessa macchina, stesso minuto: l'unica differenza è un bit. Con il bit a 1 i quattro nomi — italiano accentato, tedesco con umlaut, giapponese e cirillico — appaiono perfetti. Con il bit a 0 vengono distrutti, pur restando il payload intatto al byte.

Esplora file mostra quattro nomi di file illeggibili all'interno di un archivio ZIP con nomi UTF-8.
Gli stessi quattro file del suo gemello, con il solo bit 11 azzerato. Le dimensioni sono corrette e il contenuto è intatto: a essere distrutti sono soltanto i nomi.

Qui però il banco corregge quello che si legge normalmente sull'argomento, compresa la documentazione formale. La ricaduta di Windows non è su CP437, come prescrive l'appendice D: è sulla code page OEM del sistema, che su questa macchina italiana è la 850. La differenza è dimostrabile su un singolo byte, e l'ho verificata indipendentemente decodificando le stringhe osservate: il byte A9 diventa ® in CP850 e in CP437, e la stringa che Esplora file mostra a schermo contiene il primo, non il secondo. Python zipfile, che applica lo standard alla lettera, produce infatti una stringa diversa da quella di Windows sullo stesso identico file.

Motore Nome UTF-8 senza bit 11 Nome CP437 conforme
Esplora file (zipfldr.dll) citt├á-perch├®-cos├¼.txt — CP850 café.txtcorretto
tar / libarchive citt├á-perch├®-cos├¼.txt — CP850 café.txt — corretto
Python zipfile citt├á-perch├⌐-cos├¼.txt — CP437 café.txt — corretto
Expand-Archive (.NET) città -perché-così.txt — CP1252 caf‚.txt — sbagliato
7-Zip corretto (euristica di autorilevamento) caf + U+EF82 — sbagliato

Da questa tabella discendono due conseguenze che vale la pena esplicitare. La prima è che lo stesso archivio si storpia in modo diverso a seconda della lingua del sistema: su una macchina statunitense, dove la code page OEM è la 437, Esplora file coinciderebbe con lo standard — per combinazione, non per conformità. La seconda è che sull'archivio legacy fatto a regola d'arte, con il byte CP437 e il bit 11 correttamente azzerato, Windows ha ragione e 7-Zip ha torto: la shell rende un vero café.txt con la é a U+00E9, mentre 7-Zip trasforma il byte in un carattere dell'area a uso privato e .NET lo decodifica come CP1252.

La tesi «Windows non sa gestire i caratteri non ASCII» è quindi falsa. Windows fa esattamente quello che l'archivio dichiara di contenere. Il guasto non è incompetenza sulla codifica, è fiducia in una dichiarazione sbagliata — con l'aggravante che la dichiarazione sbagliata è ormai la norma di fatto in mezzo mondo POSIX, e con la variante non standard di usare la code page OEM locale al posto di quella prescritta.

La casella «Beta: UTF-8» è uno scambio, non un rimedio

Nel pannello di controllo, sotto Area geografica, Opzioni di amministrazione, Modifica impostazioni locali del sistema, esiste una casella etichettata «Beta: utilizzare Unicode UTF-8 per il supporto della lingua a livello mondiale». È disattivata di serie, sepolta in tre livelli di finestre e richiede un riavvio. Ho rifatto l'intero banco con quella casella attiva, verificando il cambio sul registro — le voci ACP, OEMCP e MACCP passano tutte a 65001 — e non fidandomi del pannello.

Finestra Impostazioni area di Windows con la casella Beta: utilizzare Unicode UTF-8 spuntata.
La casella in questione, disattivata per impostazione predefinita e raggiungibile solo dal vecchio pannello di controllo. Richiede il riavvio del sistema.

Su settantasei misure automatiche, il confronto campo per campo con la configurazione predefinita dà due sole differenze, entrambe di soli nomi. Tutti gli stati, tutti i conteggi di file estratti, tutti i codici di uscita restano identici: il metodo di compressione non supportato resta non supportato, la soglia dei 260 caratteri resta dov'era, l'AES-256 resta inestraibile, il collegamento simbolico resta appiattito. La casella tocca esclusivamente la resa dei nomi.

E lì fa due cose opposte. Ripara integralmente l'archivio UTF-8 senza bit 11: quattro nomi su quattro, tre alfabeti, zero mojibake, dove prima comparivano stringhe illeggibili. È la tesi nella sua forma più forte, perché dimostra che Windows quell'archivio sapeva leggerlo, e a impedirglielo era una casella disattivata per impostazione predefinita.

Lo stesso archivio ZIP riaperto dopo l'attivazione della casella UTF-8: i quattro nomi appaiono corretti.
Lo stesso archivio della figura precedente, stesso file e stesso hash, riaperto dopo il riavvio con la casella attiva. Italiano accentato, tedesco, giapponese e cirillico: quattro nomi su quattro corretti.

Nello stesso movimento, però, rompe l'archivio legacy conforme: il byte CP437 finisce in un decodificatore UTF-8, dove è un byte di continuazione isolato, e diventa U+FFFD, il carattere di sostituzione. Non è un mojibake reversibile come gli altri: è una perdita, e il file finisce su disco con quel carattere nel nome.

Il nome café.txt mostrato da Esplora file con il carattere di sostituzione al posto della lettera accentata.
L'effetto collaterale: lo stesso interruttore che ripara l'archivio moderno danneggia quello legacy conforme. Al posto della é compare U+FFFD, e il byte originale non è più ricostruibile.

Il taglio fra i motori che ne risentono e quelli che no è pulito e non era prevedibile a tavolino: la casella muove zipfldr.dll e .NET, cioè i due motori che si appoggiano alle code page di sistema, e non tocca affatto libarchive, Python e 7-Zip, che portano la propria logica di codifica. Chi consiglia di attivare quella casella senza dire la seconda metà della storia sta dando un consiglio incompleto: ripara il caso oggi più frequente e rompe quello storicamente corretto.

Il silenzio è peggio dell'errore

Se dovessi indicare la cosa più insidiosa emersa dal banco, non sceglierei nessuna delle finestre di errore. Sceglierei i casi in cui Windows non dice niente.

L'archivio con i prefissi POSIX contiene tre entry: due cominciano con ./, come è normalissimo negli archivi generati su Linux e macOS, e una contiene un backslash nel nome. Esplora file lo apre senza errori, senza avvisi e senza codici, ed estrae un file su tre. Le due entry con il prefisso ./ non vengono elencate, non vengono estratte e non vengono segnalate: semplicemente non esistono. Chi eseguiva le prove me lo ha riferito in perfetta buona fede come «funziona», perché Windows non gli aveva detto nulla; se ne è accorto soltanto il controllo sul file system. Un errore è un'informazione, questo è un silenzio.

L'archivio con il collegamento simbolico si comporta allo stesso modo. Estrae due elementi su due, nessuna finestra, nessun codice — e quello che finisce sul disco al posto del collegamento è un file di testo normale, di tredici byte, il cui contenuto è il nome del bersaglio. Nessun reparse point, nessun tipo di collegamento: una conversione silenziosa. Chi estrae quell'archivio non ha alcun modo di sapere che uno dei due file era un symlink. Vale la pena aggiungere che sulla macchina di prova l'utente non possiede il privilegio SeCreateSymbolicLinkPrivilege e la modalità sviluppatore è disattivata: se zipfldr provasse a creare il collegamento dovrebbe fallire con un errore di privilegi. Non fallisce perché non ci prova nemmeno.

E naturalmente c'è il caso dei nomi storpiati, che rientra nella stessa categoria: quattro file su quattro estratti, contenuto integro, nomi distrutti, nessuna segnalazione. In tutti e tre i casi il danno è reale e la macchina tace.

Sei convinzioni diffuse che il banco ha smentito

La parte più utile di un esperimento è quella in cui contraddice chi lo ha progettato. Sei delle ipotesi di partenza sono cadute, e quasi tutte nella stessa direzione: Windows è più permissivo del previsto e molto meno loquace.

Si legge ovunque che gli archivi generati in streaming da Java o da PHP, con il Data Descriptor privo della firma opzionale, mandino in crisi il parser di Windows. Non accade: i due archivi gemelli, uno con la firma e uno senza, si aprono ed estraggono in modo indistinguibile, con file delle stesse identiche dimensioni.

Si legge che Windows confronti byte per byte il Local File Header con la Central Directory e rifiuti l'archivio in caso di discrepanza. Non accade: sull'archivio in cui la prima entry si chiama alpha.txt nell'intestazione locale e omega.txt nell'indice finale, la shell segue la Central Directory come fonte di verità — esattamente come 7-Zip — e produce un file con SHA-256 identico, senza un avviso. Il comportamento descritto esiste davvero, ma appartiene a Python zipfile, che è l'unico dei cinque motori ad accorgersi del disallineamento e a fermarsi con un BadZipFile. È un caso da manuale di bug attribuito al software sbagliato, e sospetto che l'equivoco nasca dal fatto che la discussione originale su quel comportamento si svolge nel bug tracker di Python.

Si legge che Windows supporti soltanto i metodi 0 (Store) e 8 (Deflate) e rifiuti tutto il resto. L'archivio dichiarato con il metodo 9 viene invece estratto correttamente da Esplora file, con SHA-256 identico a quello prodotto da 7-Zip, mentre sullo stesso file Expand-Archive e tar falliscono entrambi dichiarando il metodo non supportato. L'imputato è, in questo caso, il più permissivo dei tre. Con una cautela doverosa: quell'archivio è un flusso Deflate legalmente dichiarato come metodo 9, quindi la prova dimostra che la shell non rifiuta il metodo 9 in quanto tale, non che implementi Deflate64 completo con la finestra estesa a 64 KB.

Si legge che gli archivi con molte migliaia di entry esauriscano l'heap di zipfldr.dll e provochino il messaggio di cartella non valida, sulla scorta di un caso documentato oltre le quindicimila entry. Con ventimila entry l'estrazione è arrivata in fondo senza perdere un file: ventimilauno su ventimilauno. Il consumo di memoria di explorer.exe è cresciuto di ottantuno megabyte, il che non è un esaurimento di nulla. Il dato interessante è un altro, ed è emerso dal campionamento: durante l'operazione gli handle aperti dal processo sono passati da 8.822 a 11.078. È la firma di un motore che apre e chiude descrittori uno per uno invece di lavorare in streaming, e spiega la lentezza — 97 secondi contro i 7,9 di tar, dodici volte tanto — molto meglio di qualunque teoria sulla memoria. È lenta, non rotta.

Si legge che i nomi di device DOS riservati — CON, NUL, AUX, COM1 — non possano essere creati su Windows nemmeno con un'estensione. Su questa build vengono creati tutti e sei, con il nome intatto, e sono file veri e leggibili, non redirezioni verso i device.

Infine, l'ipotesi da cui dipendeva una correzione che avevo intenzione di pubblicare: che il collegamento simbolico producesse un errore di privilegi con un codice ben preciso. Non compare nessun codice, perché non compare nessun errore. Su una fonte che avevo intenzione di correggere ho finito per non pubblicare nulla, il che è esattamente il motivo per cui vale la pena costruire un banco di prova invece di riscrivere quello che si trova in rete.

Esplora file non è il peggiore dei cinque

La conclusione più scomoda è che, misurando invece di dare per scontato, l'utilità nativa di Windows non risulta affatto il peggior motore del gruppo. Il primato spetta a Expand-Archive di PowerShell, e per una ragione precisa: fallisce dichiarando successo.

Sull'archivio con i caratteri riservati estrae zero file su nove senza sollevare alcuna eccezione, riprodotto due volte in cartella pulita: il comando termina regolarmente e la cartella di destinazione è vuota. Sull'archivio ZipCrypto dichiara l'operazione riuscita e scrive su disco cinquantatré byte di flusso cifrato grezzo dentro un file con estensione .txt — sono i 41 byte di testo in chiaro più i 12 byte di intestazione ZipCrypto, quindi non un troncamento ma il contenuto crudo scambiato per il file. Sull'archivio AES lascia un file da zero byte. Negli stessi tre casi la shell o fallisce dichiarandolo, o non lascia residui.

Nella stessa direzione va il risultato sull'archivio legacy conforme, dove 7-Zip sbaglia e Windows no. Un articolo che si limitasse a concludere «usate 7-Zip e non pensateci più» sarebbe più comodo da scrivere e meno onesto: 7-Zip resta lo strumento giusto per la stragrande maggioranza dei casi, ma non è infallibile, e la sua euristica di autorilevamento che salva l'archivio moderno è la stessa che gli fa sbagliare quello vecchio.

Cosa farne, in pratica

Per chi scrive software che genera archivi ZIP destinati a utenti Windows, le regole che emergono dal banco sono poche e tutte verificabili. La più importante riguarda la lunghezza: nessun nome di entry deve superare i 256 caratteri, terminatore e radice inclusi nel conteggio, e il margine va calcolato sul nome interno perché la destinazione di estrazione non conta nulla. Il fatto che una sola entry oltre soglia renda irraggiungibile l'intero archivio trasforma questo controllo da buona pratica in requisito, specie in tutti i flussi che derivano nomi di file da URL o da percorsi arbitrari.

Subito dopo viene il bit 11: se si scrivono nomi in UTF-8 va alzato, sempre, perché la ricaduta legacy di Windows non è nemmeno quella prevista dallo standard ma dipende dalla lingua del sistema di chi riceve l'archivio. E poi la scelta dei metodi: per un archivio destinato a essere aperto con un doppio clic su Windows, Deflate resta l'unica scelta ragionevole, e la cifratura AES va esclusa a meno di essere certi che il destinatario usi uno strumento dedicato — non perché Windows la rifiuti con un messaggio comprensibile, ma perché non la rifiuta affatto, si limita a fallire senza spiegazioni e senza nemmeno chiedere la password.

Per chi invece un archivio se lo trova respinto, la diagnosi si fa in trenta secondi e senza ricomprimere niente. Un 7z t o un unzip -t dicono immediatamente se l'archivio è integro, e nella quasi totalità dei casi lo è. Se lo è, la domanda successiva è quanto misuri l'entry più lunga, perché su questa build è l'unica cosa che produce davvero il messaggio della discordia. Ricomprimere alla cieca, che è la prima reazione istintiva, è invece il modo migliore per perdere tempo e talvolta anche dati.

Fin dove arriva questa prova

Tutto quanto precede è stato misurato su una macchina, con una build, in una lingua. Dove i risultati contraddicono fonti pubbliche non sto affermando che quelle fonti abbiano sempre avuto torto: sto affermando che su Windows 11 25H2 build 26200.8875 in italiano, oggi, le cose stanno così. La ricaduta su CP850 anziché su CP437, in particolare, è per costruzione dipendente dalla lingua del sistema e su una macchina configurata diversamente darà un risultato diverso.

Il banco non ha toccato affatto il versante che negli ultimi due anni ha fatto più rumore, cioè l'integrazione di libarchive in Windows 11 per il supporto nativo di RAR, 7Z e TAR, con la sua scia di vulnerabilità. Non ho provato nessuno di quei formati, quindi su quel capitolo non ho niente di sperimentale da aggiungere e non fingo di averlo. Restano poi due misure che dichiaro per quello che sono: il rallentamento osservato alla seconda estrazione dell'archivio da ventimila file è stato estrapolato da un throughput costante e non cronometrato dall'inizio, e la spiegazione che me ne sono dato — un costo per file che cresce con il numero di oggetti nel volume di destinazione, dato che nello stesso momento tar non rallenta affatto — resta un'ipotesi non verificata.

Il banco di prova è riproducibile: diciannove archivi, un generatore Python, uno script PowerShell che passa ogni file ai quattro motori automatizzabili e verifica gli hash prima di cominciare. Chiunque voglia rifare le misure sulla propria build, in un'altra lingua o su una versione diversa di Windows, può scrivermi e glielo mando. Sarei particolarmente curioso di sapere se la fascia dei tre caratteri fra 257 e 259 — quella in cui l'archivio si apre vuoto senza dire niente — si comporti allo stesso modo su un sistema in inglese.