This is an automated email from the ASF dual-hosted git repository.
pjfanning pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git
The following commit(s) were added to refs/heads/trunk by this push:
new 3df1a5a8af improve ZipArchiveFakeEntry getSize (#1150)
3df1a5a8af is described below
commit 3df1a5a8af35216b05c01fac96dfd2fd06ce2f89
Author: PJ Fanning <[email protected]>
AuthorDate: Wed Jun 24 12:53:56 2026 +0100
improve ZipArchiveFakeEntry getSize (#1150)
* improve ZipArchiveFakeEntry getSize
* add tests
---
.../poi/openxml4j/util/ZipArchiveFakeEntry.java | 22 ++++-
.../util/ZipInputStreamZipEntrySource.java | 3 +-
.../openxml4j/util/TestZipArchiveFakeEntry.java | 101 +++++++++++++++++++++
3 files changed, 122 insertions(+), 4 deletions(-)
diff --git
a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipArchiveFakeEntry.java
b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipArchiveFakeEntry.java
index f617a8dde9..5ea9394c44 100644
---
a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipArchiveFakeEntry.java
+++
b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipArchiveFakeEntry.java
@@ -64,6 +64,7 @@ public final class ZipArchiveFakeEntry extends
ZipArchiveEntry implements Closea
private byte[] data;
private File tempFile;
private EncryptedTempData encryptedTempData;
+ private final long numberOfBytes;
ZipArchiveFakeEntry(ZipArchiveEntry entry, InputStream inp) throws
IOException {
super(entry.getName());
@@ -77,13 +78,13 @@ public final class ZipArchiveFakeEntry extends
ZipArchiveEntry implements Closea
if (ZipInputStreamZipEntrySource.shouldEncryptTempFiles()) {
encryptedTempData = new EncryptedTempData();
try (OutputStream os =
encryptedTempData.getOutputStream()) {
- IOUtils.copy(inp, os);
+ numberOfBytes = IOUtils.copy(inp, os);
}
} else {
tempFile = TempFile.createTempFile("poi-zip-entry",
".tmp");
LOG.atInfo().log("Creating temp file {} for zip entry {}
of size {} bytes",
tempFile.getAbsolutePath(), entry.getName(),
entrySize);
- IOUtils.copy(inp, tempFile);
+ numberOfBytes = IOUtils.copy(inp, tempFile);
}
success = true;
} finally {
@@ -103,9 +104,15 @@ public final class ZipArchiveFakeEntry extends
ZipArchiveEntry implements Closea
// Grab the de-compressed contents for later
data = (entrySize == -1) ? IOUtils.toByteArrayWithMaxLength(inp,
getMaxEntrySize()) :
IOUtils.toByteArray(inp, entrySize, getMaxEntrySize(),
"ZipArchiveFakeEntry.setMaxEntrySize()");
+ numberOfBytes = data.length;
}
}
+ @Override
+ public long getSize() {
+ return numberOfBytes;
+ }
+
/**
* Returns zip entry.
* @return input stream
@@ -150,4 +157,15 @@ public final class ZipArchiveFakeEntry extends
ZipArchiveEntry implements Closea
}
}
}
+
+ // open for testing
+ boolean isUnencryptedTempFileBacked() {
+ return tempFile != null && tempFile.exists();
+ }
+
+ // open for testing
+ boolean isEncryptedTempFileBacked() {
+ return encryptedTempData != null;
+ }
+
}
diff --git
a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
index 71be7d3868..8c92298057 100644
---
a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
+++
b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
@@ -29,7 +29,6 @@ import java.util.Set;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.poi.openxml4j.opc.internal.InvalidZipException;
import org.apache.poi.util.IOUtils;
-import org.apache.poi.util.StringUtil;
/**
* Provides a way to get at all the ZipEntries
@@ -44,7 +43,7 @@ public class ZipInputStreamZipEntrySource implements
ZipEntrySource {
private static boolean encryptTempFiles = false;
private final Map<String, ZipArchiveFakeEntry> zipEntries = new
HashMap<>();
- private InputStream streamToClose;
+ private final InputStream streamToClose;
/**
* Set the threshold at which a zip entry is regarded as too large for
holding in memory
diff --git
a/poi-ooxml/src/test/java/org/apache/poi/openxml4j/util/TestZipArchiveFakeEntry.java
b/poi-ooxml/src/test/java/org/apache/poi/openxml4j/util/TestZipArchiveFakeEntry.java
new file mode 100644
index 0000000000..366a1d4d19
--- /dev/null
+++
b/poi-ooxml/src/test/java/org/apache/poi/openxml4j/util/TestZipArchiveFakeEntry.java
@@ -0,0 +1,101 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.openxml4j.util;
+
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
+import org.apache.poi.util.IOUtils;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.Isolated;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+@Isolated // changes static values, so other tests should not run at the same
time
+public class TestZipArchiveFakeEntry {
+ @Test
+ void testSize() throws IOException {
+ runTestSize(false, false);
+ }
+
+ @Test
+ void testSizeTempFileBacked() throws IOException {
+ ZipInputStreamZipEntrySource.setThresholdBytesForTempFiles(0);
+ try {
+ runTestSize(true, false);
+ } finally {
+ ZipInputStreamZipEntrySource.setThresholdBytesForTempFiles(-1);
+ }
+ }
+
+ @Test
+ void testSizeEncryptedTempFileBacked() throws IOException {
+ ZipInputStreamZipEntrySource.setThresholdBytesForTempFiles(0);
+ ZipInputStreamZipEntrySource.setEncryptTempFiles(true);
+ try {
+ runTestSize(false, true);
+ } finally {
+ ZipInputStreamZipEntrySource.setThresholdBytesForTempFiles(-1);
+ ZipInputStreamZipEntrySource.setEncryptTempFiles(false);
+ }
+ }
+
+ @Test
+ void testInvalidEntrySize() throws IOException {
+ final long fakeLen = 123;
+ final String fakeValue = "fakeValue";
+ ZipArchiveEntry entry = new ZipArchiveEntry("hack123") {
+ @Override
+ public long getSize() {
+ return fakeLen;
+ }
+ };
+ UnsynchronizedByteArrayOutputStream baos =
UnsynchronizedByteArrayOutputStream.builder().get();
+ final byte[] data = fakeValue.getBytes(StandardCharsets.UTF_8);
+ baos.write(data);
+ // the data in the stream is less than the fakeLen in the entry
+ // this is a regression test for the existing internal behaviour - if
we choose to change the
+ // behaviour in the future, this test can be updated
+ assertThrows(EOFException.class, () -> new ZipArchiveFakeEntry(entry,
baos.toInputStream()));
+ }
+
+ static void runTestSize(boolean unencryptedTempFileExpected,
+ boolean encryptedTempFileExpected) throws
IOException {
+ final String fakeEntryName = "hack123";
+ final String fakeValue = "fakeValue";
+ ZipArchiveEntry entry = new ZipArchiveEntry(fakeEntryName);
+ UnsynchronizedByteArrayOutputStream baos =
UnsynchronizedByteArrayOutputStream.builder().get();
+ final byte[] data = fakeValue.getBytes(StandardCharsets.UTF_8);
+ baos.write(data);
+ try (ZipArchiveFakeEntry zipArchiveFakeEntry = new
ZipArchiveFakeEntry(entry, baos.toInputStream())) {
+ assertEquals(fakeEntryName, zipArchiveFakeEntry.getName());
+ UnsynchronizedByteArrayOutputStream baos2 =
UnsynchronizedByteArrayOutputStream.builder().get();
+ assertEquals(data.length,
IOUtils.copy(zipArchiveFakeEntry.getInputStream(), baos2));
+ assertEquals(fakeValue,
baos2.toString(StandardCharsets.UTF_8.name()));
+ assertEquals(data.length, zipArchiveFakeEntry.getSize());
+ assertEquals(unencryptedTempFileExpected,
zipArchiveFakeEntry.isUnencryptedTempFileBacked());
+ assertEquals(encryptedTempFileExpected,
zipArchiveFakeEntry.isEncryptedTempFileBacked());
+ }
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]