S’agit-il d’un bogue dans la classe Java GZipInputStream?

J’ai remarqué que certains de mes codes de décodage gzip ne semblaient pas détecter les données corrompues. Je pense avoir tracé le problème jusqu’à la classe Java GZipInputStream. En particulier, il semble que lorsque vous lisez l’intégralité du stream avec un seul appel “en lecture”, les données corrompues ne déclenchent pas une exception IOException. Si vous lisez le stream en 2 appels ou plus sur les mêmes données corrompues, une exception est déclenchée.

Je voulais voir ce que la communauté ici pensait avant d’envisager de déposer un rapport de bogue.

EDIT: J’ai modifié mon exemple parce que le dernier n’a pas illustré aussi clairement ce que je perçois comme étant l’enjeu. Dans ce nouvel exemple, un tampon de 10 octets est gzippé, un octet du tampon gzippé est modifié, puis il est non gzippé. L’appel à ‘GZipInputStream.read’ renvoie 10 sous forme de nombre d’octets lus, ce qui correspond à ce que vous attendez d’un tampon de 10 octets. Néanmoins, le tampon décompressé est différent de celui d’origine (en raison de la corruption). Aucune exception n’est levée. J’ai remarqué que l’appel de “disponible” après la lecture renvoie “1” au lieu de “0”, ce qui serait le cas si l’EOF avait été atteint.

Voici la source:

@Test public void gzip() { try { int length = 10; byte[] bytes = new byte[]{12, 19, 111, 14, -76, 34, 60, -43, -91, 101}; System.out.println(Arrays.toSsortingng(bytes)); //Gzip the byte array ByteArrayOutputStream baos = new ByteArrayOutputStream(); GZIPOutputStream gos = new GZIPOutputStream(baos); gos.write(bytes); gos.finish(); byte[] zipped = baos.toByteArray(); //Alter one byte of the gzipped array. //This should be detected by gzip crc-32 checksum zipped[15] = (byte)(0); //Unzip the modified array ByteArrayInputStream bais = new ByteArrayInputStream(zipped); GZIPInputStream gis = new GZIPInputStream(bais); byte[] unzipped = new byte[length]; int numRead = gis.read(unzipped); System.out.println("NumRead: " + numRead); System.out.println("Available: " + gis.available()); //The unzipped array is now [12, 19, 111, 14, -80, 0, 0, 0, 10, -118]. //No IOException was thrown. System.out.println(Arrays.toSsortingng(unzipped)); //Assert that the input and unzipped arrays are equal (they aren't) org.junit.Assert.assertArrayEquals(unzipped, bytes); } catch (IOException e) { e.printStackTrace(); } } 

Décidé de faire le test:

Ce que tu as manqué gis.read(unzipped) renvoie 1, il n’a donc lu qu’un seul octet. Vous ne pouvez pas vous plaindre, ce n’est pas la fin du stream.

Le prochain read() lance “Corrupt GZIP trailer” .

Donc tout va bien! ( et il n’y a pas de bugs, du moins dans GZIPInputStream )