throw exception if xlsx contains duplicate file names

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1918802 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2024-07-01 22:40:18 +00:00
parent 600bf8c4b3
commit 03b0742ad3
5 changed files with 60 additions and 17 deletions

View File

@ -35,6 +35,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.openxml4j.opc.internal.InvalidZipException;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Removal;
@ -62,8 +63,12 @@ public final class PackageHelper {
public static OPCPackage open(InputStream stream, boolean closeStream) throws IOException {
try {
return OPCPackage.open(stream, closeStream);
} catch (InvalidFormatException e){
throw new POIXMLException(e);
} catch (InvalidFormatException e) {
final Throwable cause = e.getCause();
if (cause instanceof IOException) {
throw (IOException) cause;
}
throw new IOException(e);
} finally {
if (closeStream) {
stream.close();

View File

@ -50,6 +50,7 @@ import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
import org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException;
import org.apache.poi.openxml4j.opc.internal.ContentType;
import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
import org.apache.poi.openxml4j.opc.internal.InvalidZipException;
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller;
@ -193,7 +194,7 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
}
/**
* Open an user provided {@link ZipEntrySource} with read-only permission.
* Open a user provided {@link ZipEntrySource} with read-only permission.
* This method can be used to stream data into POI.
* Opposed to other open variants, the data is read as-is, e.g. there aren't
* any zip-bomb protection put in place.
@ -202,8 +203,7 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
* @return A Package object
* @throws InvalidFormatException if a parsing error occur.
*/
public static OPCPackage open(ZipEntrySource zipEntry)
throws InvalidFormatException {
public static OPCPackage open(ZipEntrySource zipEntry) throws InvalidFormatException {
OPCPackage pack = new ZipPackage(zipEntry, PackageAccess.READ);
try {
if (pack.partList == null) {
@ -282,7 +282,12 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
throw new IllegalArgumentException("file must not be a directory");
}
OPCPackage pack = new ZipPackage(file, access); //NOSONAR
final OPCPackage pack;
try {
pack = new ZipPackage(file, access); //NOSONAR
} catch (InvalidOperationException e) {
throw new InvalidFormatException(e.getMessage(), e);
}
try {
if (pack.partList == null && access != PackageAccess.WRITE) {
pack.getParts();
@ -316,8 +321,12 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
*/
public static OPCPackage open(InputStream in) throws InvalidFormatException,
IOException {
OPCPackage pack = new ZipPackage(in, PackageAccess.READ_WRITE);
final OPCPackage pack;
try {
pack = new ZipPackage(in, PackageAccess.READ_WRITE);
} catch (InvalidZipException e) {
throw new InvalidFormatException(e.getMessage(), e);
} try {
if (pack.partList == null) {
pack.getParts();
}
@ -348,7 +357,12 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
*/
public static OPCPackage open(InputStream in, boolean closeStream) throws InvalidFormatException,
IOException {
OPCPackage pack = new ZipPackage(in, PackageAccess.READ_WRITE, closeStream);
final OPCPackage pack;
try {
pack = new ZipPackage(in, PackageAccess.READ_WRITE, closeStream);
} catch (InvalidZipException e) {
throw new InvalidFormatException(e.getMessage(), e);
}
try {
if (pack.partList == null) {
pack.getParts();

View File

@ -21,9 +21,12 @@ import java.io.InputStream;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.poi.openxml4j.opc.internal.InvalidZipException;
/**
* Provides a way to get at all the ZipEntries
@ -90,12 +93,18 @@ public class ZipInputStreamZipEntrySource implements ZipEntrySource {
* @see #setThresholdBytesForTempFiles
*/
public ZipInputStreamZipEntrySource(ZipArchiveThresholdInputStream inp) throws IOException {
final Set<String> filenames = new HashSet<>();
for (;;) {
final ZipArchiveEntry zipEntry = inp.getNextEntry();
if (zipEntry == null) {
break;
}
zipEntries.put(zipEntry.getName(), new ZipArchiveFakeEntry(zipEntry, inp));
String name = zipEntry.getName();
if (filenames.contains(name)) {
throw new InvalidZipException("Input file contains more than 1 entry with the name " + name);
}
filenames.add(name);
zipEntries.put(name, new ZipArchiveFakeEntry(zipEntry, inp));
}
streamToClose = inp;

View File

@ -254,8 +254,8 @@ public class ZipSecureFile extends ZipFile {
}
private void validateEntryNames() throws IOException {
Enumeration<ZipArchiveEntry> en = getEntries();
Set<String> filenames = new HashSet<>();
final Enumeration<ZipArchiveEntry> en = getEntries();
final Set<String> filenames = new HashSet<>();
while (en.hasMoreElements()) {
String name = en.nextElement().getName();
if (filenames.contains(name)) {

View File

@ -27,7 +27,6 @@ import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.ooxml.TrackingInputStream;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
import org.apache.poi.openxml4j.opc.ContentTypes;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
@ -38,6 +37,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.ZipPackage;
import org.apache.poi.openxml4j.opc.internal.FileHelper;
import org.apache.poi.openxml4j.opc.internal.InvalidZipException;
import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
import org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource;
@ -1448,13 +1448,28 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
}
}
@Test
void testDuplicateFileReadAsOPCFile() {
assertThrows(InvalidFormatException.class, () -> {
try (OPCPackage pkg = OPCPackage.open(getSampleFile("duplicate-file.xlsx"), PackageAccess.READ)) {
// expect exception here
}
});
}
@Test
void testDuplicateFileReadAsFile() {
assertThrows(InvalidOperationException.class, () -> {
try (
OPCPackage pkg = OPCPackage.open(getSampleFile("duplicate-file.xlsx"), PackageAccess.READ);
XSSFWorkbook wb = new XSSFWorkbook(pkg)
) {
assertThrows(InvalidFormatException.class, () -> {
try (XSSFWorkbook wb = new XSSFWorkbook(getSampleFile("duplicate-file.xlsx"))) {
// expect exception here
}
});
}
@Test
void testDuplicateFileReadAsStream() {
assertThrows(InvalidZipException.class, () -> {
try (XSSFWorkbook wb = new XSSFWorkbook(openSampleFileStream("duplicate-file.xlsx"))) {
// expect exception here
}
});