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 2019/08/16 06:10:50 UTC
[commons-compress] branch master updated: COMPRESS-479 use strategy
pattern to handle unparseable extra fields
This is an automated email from the ASF dual-hosted git repository.
bodewig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git
The following commit(s) were added to refs/heads/master by this push:
new f43c608 COMPRESS-479 use strategy pattern to handle unparseable extra fields
f43c608 is described below
commit f43c608cf422817a3280cb2a2cbe749ee090d9d3
Author: Stefan Bodewig <bo...@apache.org>
AuthorDate: Fri Aug 16 08:10:12 2019 +0200
COMPRESS-479 use strategy pattern to handle unparseable extra fields
---
.../compress/archivers/zip/ExtraFieldUtils.java | 67 ++++++++++++----------
.../zip/UnparseableExtraFieldBehavior.java | 49 ++++++++++++++++
2 files changed, 86 insertions(+), 30 deletions(-)
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ExtraFieldUtils.java b/src/main/java/org/apache/commons/compress/archivers/zip/ExtraFieldUtils.java
index 24e4893..aa54bac 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ExtraFieldUtils.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ExtraFieldUtils.java
@@ -134,7 +134,7 @@ public class ExtraFieldUtils {
* @since 1.1
*/
public static ZipExtraField[] parse(final byte[] data, final boolean local,
- final UnparseableExtraField onUnparseableData)
+ final UnparseableExtraFieldBehavior onUnparseableData)
throws ZipException {
return parse(data, local, onUnparseableData, ParseErrorBehavior.THROW);
}
@@ -157,7 +157,7 @@ public class ExtraFieldUtils {
* @since 1.19
*/
public static ZipExtraField[] parse(final byte[] data, final boolean local,
- final UnparseableExtraField onUnparseableData,
+ final UnparseableExtraFieldBehavior onUnparseableData,
final ParseErrorBehavior onParseError)
throws ZipException {
final List<ZipExtraField> v = new ArrayList<>();
@@ -167,35 +167,15 @@ public class ExtraFieldUtils {
final ZipShort headerId = new ZipShort(data, start);
final int length = new ZipShort(data, start + 2).getValue();
if (start + WORD + length > data.length) {
- switch(onUnparseableData.getKey()) {
- case UnparseableExtraField.THROW_KEY:
- throw new ZipException("Bad extra field starting at "
- + start + ". Block length of "
- + length + " bytes exceeds remaining"
- + " data of "
- + (data.length - start - WORD)
- + " bytes.");
- case UnparseableExtraField.READ_KEY:
- final UnparseableExtraFieldData field =
- new UnparseableExtraFieldData();
- if (local) {
- field.parseFromLocalFileData(data, start,
- data.length - start);
- } else {
- field.parseFromCentralDirectoryData(data, start,
- data.length - start);
- }
+ ZipExtraField field = onUnparseableData.onUnparseableExtraField(data, start, data.length - start,
+ local, length);
+ if (field != null) {
v.add(field);
- //$FALL-THROUGH$
- case UnparseableExtraField.SKIP_KEY:
- // since we cannot parse the data we must assume
- // the extra field consumes the whole rest of the
- // available data
- break LOOP;
- default:
- throw new ZipException("Unknown UnparseableExtraField key: "
- + onUnparseableData.getKey());
}
+ // since we cannot parse the data we must assume
+ // the extra field consumes the whole rest of the
+ // available data
+ break LOOP;
}
switch (onParseError) {
case MAKE_UNRECOGNIZED:
@@ -328,7 +308,7 @@ public class ExtraFieldUtils {
*
* @since 1.1
*/
- public static final class UnparseableExtraField {
+ public static final class UnparseableExtraField implements UnparseableExtraFieldBehavior {
/**
* Key for "throw an exception" action.
*/
@@ -373,6 +353,33 @@ public class ExtraFieldUtils {
* @return the key
*/
public int getKey() { return key; }
+
+ @Override
+ public ZipExtraField onUnparseableExtraField(byte[] data, int off, int len, boolean local,
+ int claimedLength) throws ZipException {
+ switch(key) {
+ case THROW_KEY:
+ throw new ZipException("Bad extra field starting at "
+ + off + ". Block length of "
+ + claimedLength + " bytes exceeds remaining"
+ + " data of "
+ + (len - WORD)
+ + " bytes.");
+ case READ_KEY:
+ final UnparseableExtraFieldData field = new UnparseableExtraFieldData();
+ if (local) {
+ field.parseFromLocalFileData(data, off, len);
+ } else {
+ field.parseFromCentralDirectoryData(data, off, len);
+ }
+ return field;
+ case SKIP_KEY:
+ return null;
+ default:
+ throw new ZipException("Unknown UnparseableExtraField key: " + key);
+ }
+ }
+
}
/**
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/UnparseableExtraFieldBehavior.java b/src/main/java/org/apache/commons/compress/archivers/zip/UnparseableExtraFieldBehavior.java
new file mode 100644
index 0000000..09d596a
--- /dev/null
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/UnparseableExtraFieldBehavior.java
@@ -0,0 +1,49 @@
+/*
+ * 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.archivers.zip;
+
+import java.util.zip.ZipException;
+
+/**
+ * Handles extra field data that doesn't follow the recommended
+ * pattern for extra fields with a two-byte key and a two-byte length.
+ *
+ * @since 1.19
+ */
+public interface UnparseableExtraFieldBehavior {
+ /**
+ * Decides what to do with extra field data that doesn't follow the recommended pattern.
+ *
+ * @param data the array of extra field data
+ * @param off offset into data where the unparseable data starts
+ * @param len the length of unparseable data
+ * @param local whether the extra field data stems from the local
+ * file header. If this is false then the data is part if the
+ * central directory header extra data.
+ * @param claimedLength length of the extra field claimed by the
+ * third and forth byte if it did follow the recommended pattern
+ *
+ * @return null if the data should be ignored or an extra field
+ * implementation that represents the data
+ * @throws ZipException if an error occurs or unparseable extra
+ * fields must not be accepted
+ */
+ ZipExtraField onUnparseableExtraField(byte[] data, int off, int len, boolean local,
+ int claimedLength) throws ZipException;
+}