You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2021/06/06 05:42:50 UTC
[commons-compress] 01/01: turn RuntimeExceptions into IOExceptions
This is an automated email from the ASF dual-hosted git repository.
bodewig pushed a commit to branch catch-RuntimeExceptions
in repository https://gitbox.apache.org/repos/asf/commons-compress.git
commit 6cb3167e9bdc92b96eed309f938fa1ec76c19444
Author: Stefan Bodewig <bo...@apache.org>
AuthorDate: Sun Jun 6 07:36:08 2021 +0200
turn RuntimeExceptions into IOExceptions
---
.../commons/compress/UnhandledInputException.java | 59 ++++++++++++++++++++++
.../compress/archivers/sevenz/SevenZFile.java | 19 ++++++-
.../commons/compress/archivers/tar/TarFile.java | 13 +++++
.../commons/compress/archivers/zip/ZipFile.java | 14 ++++-
4 files changed, 102 insertions(+), 3 deletions(-)
diff --git a/src/main/java/org/apache/commons/compress/UnhandledInputException.java b/src/main/java/org/apache/commons/compress/UnhandledInputException.java
new file mode 100644
index 0000000..920c538
--- /dev/null
+++ b/src/main/java/org/apache/commons/compress/UnhandledInputException.java
@@ -0,0 +1,59 @@
+/*
+ * 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.commons.compress;
+
+import java.io.IOException;
+
+/**
+ * Thrown if reading from an archive or compressed stream results in a RuntimeException.
+ *
+ * <p>Usually this means the input has been corrupt in a way Compress'
+ * code didn't detect by itself. If the input is not corrupt then
+ * you've found a bug in Compress and we ask you to report it.</p>
+ *
+ * @since 1.21
+ */
+public class UnhandledInputException extends IOException {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Wraps an unhandled RuntimeException for an input of unknown name.
+ */
+ public UnhandledInputException(final RuntimeException ex) {
+ this(ex, null);
+ }
+
+ /**
+ * Wraps an unhandled RuntimeException for an input with a known name.
+ *
+ * @param ex the unhandled excetion
+ * @param inputName name of the input
+ */
+ public UnhandledInputException(final RuntimeException ex, final String inputName) {
+ super(buildMessage(inputName), ex);
+ }
+
+ private static String buildMessage(final String name) {
+ return "Either the input"
+ + (name == null ? "" : " " + name)
+ + " is corrupt or you have found a bug in Apache Commons Compress. Please report it at"
+ + " https://issues.apache.org/jira/browse/COMPRESS if you think this is a bug.";
+ }
+}
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
index f4bec6c..351a858 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
@@ -45,6 +45,7 @@ import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.CRC32;
+import org.apache.commons.compress.UnhandledInputException;
import org.apache.commons.compress.utils.BoundedInputStream;
import org.apache.commons.compress.utils.ByteUtils;
import org.apache.commons.compress.utils.CRC32VerifyingInputStream;
@@ -346,6 +347,8 @@ public class SevenZFile implements Closeable {
this.password = null;
}
succeeded = true;
+ } catch (RuntimeException ex) {
+ throw new UnhandledInputException(ex, fileName);
} finally {
if (!succeeded && closeOnError) {
this.channel.close();
@@ -410,7 +413,11 @@ public class SevenZFile implements Closeable {
if (entry.getName() == null && options.getUseDefaultNameForUnnamedEntries()) {
entry.setName(getDefaultName());
}
- buildDecodingStream(currentEntryIndex, false);
+ try {
+ buildDecodingStream(currentEntryIndex, false);
+ } catch (RuntimeException ex) {
+ throw new UnhandledInputException(ex);
+ }
uncompressedBytesReadFromCurrentEntry = compressedBytesReadFromCurrentEntry = 0;
return entry;
}
@@ -510,7 +517,7 @@ public class SevenZFile implements Closeable {
if (result.packSizes.length > 0 && result.files.length > 0) {
return result;
}
- } catch (final Exception ignore) {
+ } catch (Exception ignore) {
// Wrong guess...
}
}
@@ -1899,11 +1906,15 @@ public class SevenZFile implements Closeable {
* if an I/O error has occurred
*/
public int read() throws IOException {
+ try {
final int b = getCurrentStream().read();
if (b >= 0) {
uncompressedBytesReadFromCurrentEntry++;
}
return b;
+ } catch (RuntimeException ex) {
+ throw new UnhandledInputException(ex, fileName);
+ }
}
private InputStream getCurrentStream() throws IOException {
@@ -1981,6 +1992,7 @@ public class SevenZFile implements Closeable {
* if an I/O error has occurred
*/
public int read(final byte[] b, final int off, final int len) throws IOException {
+ try {
if (len == 0) {
return 0;
}
@@ -1989,6 +2001,9 @@ public class SevenZFile implements Closeable {
uncompressedBytesReadFromCurrentEntry += cnt;
}
return cnt;
+ } catch (RuntimeException ex) {
+ throw new UnhandledInputException(ex, fileName);
+ }
}
/**
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java
index e79d390..d1822e1 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarFile.java
@@ -32,6 +32,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import org.apache.commons.compress.UnhandledInputException;
import org.apache.commons.compress.archivers.zip.ZipEncoding;
import org.apache.commons.compress.archivers.zip.ZipEncodingHelper;
import org.apache.commons.compress.utils.ArchiveUtils;
@@ -239,6 +240,14 @@ public class TarFile implements Closeable {
return null;
}
+ try {
+ return getNextTarEntryInternal();
+ } catch (RuntimeException ex) {
+ throw new UnhandledInputException(ex);
+ }
+ }
+
+ private TarArchiveEntry getNextTarEntryInternal() throws IOException {
if (currEntry != null) {
// Skip to the end of the entry
repositionForwardTo(currEntry.getDataOffset() + currEntry.getSize());
@@ -678,11 +687,15 @@ public class TarFile implements Closeable {
}
final int totalRead;
+ try {
if (entry.isSparse()) {
totalRead = readSparse(entryOffset, buf, buf.limit());
} else {
totalRead = readArchive(pos, buf);
}
+ } catch (RuntimeException ex) {
+ throw new UnhandledInputException(ex);
+ }
if (totalRead == -1) {
if (buf.array().length > 0) {
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
index 8792563..cd1b01a 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
@@ -42,6 +42,7 @@ import java.util.Map;
import java.util.zip.Inflater;
import java.util.zip.ZipException;
+import org.apache.commons.compress.UnhandledInputException;
import org.apache.commons.compress.archivers.EntryStreamOffsets;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.deflate64.Deflate64CompressorInputStream;
@@ -376,6 +377,8 @@ public class ZipFile implements Closeable {
}
fillNameMap();
success = true;
+ } catch (RuntimeException ex) {
+ throw new UnhandledInputException(ex, archiveName);
} catch (final IOException e) {
throw new IOException("Error on ZipFile " + archiveName, e);
} finally {
@@ -564,7 +567,16 @@ public class ZipFile implements Closeable {
if (!(ze instanceof Entry)) {
return null;
}
- // cast validity is checked just above
+ try {
+ // cast validity is checked just above
+ return getInputStreamInternal((Entry) ze);
+ } catch (RuntimeException ex) {
+ throw new UnhandledInputException(ex);
+ }
+ }
+
+ private InputStream getInputStreamInternal(final Entry ze)
+ throws IOException {
ZipUtil.checkRequestedFeatures(ze);
final long start = getDataOffset(ze);