diff -Nur commons-compress-1.17-src_old/src/main/java/org/apache/commons/compress/archivers/zip/NioZipEncoding.java commons-compress-1.17-src/src/main/java/org/apache/commons/compress/archivers/zip/NioZipEncoding.java --- commons-compress-1.17-src_old/src/main/java/org/apache/commons/compress/archivers/zip/NioZipEncoding.java 2019-12-26 01:58:18.095645681 -0500 +++ commons-compress-1.17-src/src/main/java/org/apache/commons/compress/archivers/zip/NioZipEncoding.java 2019-12-26 01:59:05.351833877 -0500 @@ -112,7 +112,9 @@ } else if (res.isOverflow()) { int increment = estimateIncrementalEncodingSize(enc, cb.remaining()); out = ZipEncodingHelper.growBufferBy(out, increment); - } + }else if(res.isUnderflow() || res.isError()) { + break; + } } // tell the encoder we are done enc.encode(cb, out, true); diff -Nur commons-compress-1.17-src_old/src/test/java/org/apache/commons/compress/archivers/zip/NioZipEncodingTest.java commons-compress-1.17-src/src/test/java/org/apache/commons/compress/archivers/zip/NioZipEncodingTest.java --- commons-compress-1.17-src_old/src/test/java/org/apache/commons/compress/archivers/zip/NioZipEncodingTest.java 1969-12-31 19:00:00.000000000 -0500 +++ commons-compress-1.17-src/src/test/java/org/apache/commons/compress/archivers/zip/NioZipEncodingTest.java 2019-12-26 01:59:34.823951249 -0500 @@ -0,0 +1,101 @@ +/* + * *LicensedtotheApacheSoftwareFoundation(ASF)underone + * *ormorecontributorlicenseagreements.SeetheNOTICEfile + * *distributedwiththisworkforadditionalinformation + * *regardingcopyrightownership.TheASFlicensesthisfile + * *toyouundertheApacheLicense,Version2.0(the + * *"License");youmaynotusethisfileexceptincompliance + * *withtheLicense.YoumayobtainacopyoftheLicenseat + * * + * *http://www.apache.org/licenses/LICENSE-2.0 + * * + * *Unlessrequiredbyapplicablelaworagreedtoinwriting, + * *softwaredistributedundertheLicenseisdistributedonan + * *"ASIS"BASIS,WITHOUTWARRANTIESORCONDITIONSOFANY + * *KIND,eitherexpressorimplied.SeetheLicenseforthe + * *specificlanguagegoverningpermissionsandlimitations + * *undertheLicense. + * + */ +package org.apache.commons.compress.archivers.zip; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +import org.junit.Assert; +import org.junit.Test; + +public class NioZipEncodingTest { + + private static final String UMLAUTS = "\u00e4\u00f6\u00fc"; + + @Test + public void umlautToUTF16BE() { + NioZipEncoding e = new NioZipEncoding(StandardCharsets.UTF_16BE, false); + ByteBuffer bb = e.encode(UMLAUTS); + final int off = bb.arrayOffset(); + byte[] result = Arrays.copyOfRange(bb.array(), off, off + bb.limit() - bb.position()); + Assert.assertArrayEquals(UMLAUTS.getBytes(StandardCharsets.UTF_16BE), result); + } + + @Test + public void umlautToUTF8() { + NioZipEncoding e = new NioZipEncoding(StandardCharsets.UTF_8, true); + ByteBuffer bb = e.encode("\u00e4\u00f6\u00fc"); + final int off = bb.arrayOffset(); + byte[] result = Arrays.copyOfRange(bb.array(), off, off + bb.limit() - bb.position()); + Assert.assertArrayEquals(UMLAUTS.getBytes(StandardCharsets.UTF_8), result); + } + + @Test + public void umlautToISO88591() { + NioZipEncoding e = new NioZipEncoding(StandardCharsets.ISO_8859_1, true); + ByteBuffer bb = e.encode("\u00e4\u00f6\u00fc"); + final int off = bb.arrayOffset(); + byte[] result = Arrays.copyOfRange(bb.array(), off, off + bb.limit() - bb.position()); + Assert.assertArrayEquals(UMLAUTS.getBytes(StandardCharsets.ISO_8859_1), result); + } + + @Test + public void unmappableUmlauts() { + NioZipEncoding e = new NioZipEncoding(StandardCharsets.US_ASCII, false); + ByteBuffer bb = e.encode("\u00e4\u00f6\u00fc"); + final int off = bb.arrayOffset(); + byte[] result = Arrays.copyOfRange(bb.array(), off, off + bb.limit() - bb.position()); + Assert.assertEquals("%U00E4%U00F6%U00FC", new String(result, StandardCharsets.US_ASCII)); + } + + private static final String RAINBOW_EMOJI = "\ud83c\udf08"; + + @Test + public void unmappableRainbowEmoji() { + NioZipEncoding e = new NioZipEncoding(StandardCharsets.US_ASCII, false); + ByteBuffer bb = e.encode(RAINBOW_EMOJI); + final int off = bb.arrayOffset(); + byte[] result = Arrays.copyOfRange(bb.array(), off, off + bb.limit() - bb.position()); + Assert.assertEquals("%UD83C%UDF08", new String(result, StandardCharsets.US_ASCII)); + } + + @Test + public void rainbowEmojiToSurrogatePairUTF16() { + NioZipEncoding e = new NioZipEncoding(StandardCharsets.UTF_16BE, false); + ByteBuffer bb = e.encode(RAINBOW_EMOJI); + final int off = bb.arrayOffset(); + byte[] result = Arrays.copyOfRange(bb.array(), off, off + bb.limit() - bb.position()); + Assert.assertArrayEquals(RAINBOW_EMOJI.getBytes(StandardCharsets.UTF_16BE), result); + } + + @Test + public void partialSurrogatePair() { + NioZipEncoding e = new NioZipEncoding(StandardCharsets.US_ASCII, false); + ByteBuffer bb = e.encode("\ud83c"); + final int off = bb.arrayOffset(); + byte[] result = Arrays.copyOfRange(bb.array(), off, off + bb.limit() - bb.position()); + Assert.assertEquals(0, result.length); + } + + +} + +