yet another potential AIOBException in zip package
found by Earl Hood over in Ant's version of the same code
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/compress/trunk@1692044 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/UnshrinkingInputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/UnshrinkingInputStream.java
index 7210534..a09b72e 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/UnshrinkingInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/UnshrinkingInputStream.java
@@ -36,20 +36,22 @@
public UnshrinkingInputStream(InputStream inputStream) throws IOException {
super(inputStream, ByteOrder.LITTLE_ENDIAN);
- setClearCode(codeSize);
+ setClearCode(DEFAULT_CODE_SIZE);
initializeTables(MAX_CODE_SIZE);
- isUsed = new boolean[prefixes.length];
+ isUsed = new boolean[getPrefixesLength()];
for (int i = 0; i < (1 << 8); i++) {
isUsed[i] = true;
}
- tableSize = clearCode + 1;
+ setTableSize(getClearCode() + 1);
}
@Override
protected int addEntry(int previousCode, byte character) throws IOException {
+ int tableSize = getTableSize();
while ((tableSize < MAX_TABLE_SIZE) && isUsed[tableSize]) {
tableSize++;
}
+ setTableSize(tableSize);
int idx = addEntry(previousCode, character, MAX_TABLE_SIZE);
if (idx >= 0) {
isUsed[idx] = true;
@@ -60,14 +62,14 @@
private void partialClear() {
final boolean[] isParent = new boolean[MAX_TABLE_SIZE];
for (int i = 0; i < isUsed.length; i++) {
- if (isUsed[i] && prefixes[i] != -1) {
- isParent[prefixes[i]] = true;
+ if (isUsed[i] && getPrefix(i) != UNUSED_PREFIX) {
+ isParent[getPrefix(i)] = true;
}
}
- for (int i = clearCode + 1; i < isParent.length; i++) {
+ for (int i = getClearCode() + 1; i < isParent.length; i++) {
if (!isParent[i]) {
isUsed[i] = false;
- prefixes[i] = -1;
+ setPrefix(i, UNUSED_PREFIX);
}
}
}
@@ -89,19 +91,19 @@
final int code = readNextCode();
if (code < 0) {
return -1;
- } else if (code == clearCode) {
+ } else if (code == getClearCode()) {
final int subCode = readNextCode();
if (subCode < 0) {
throw new IOException("Unexpected EOF;");
} else if (subCode == 1) {
- if (codeSize < MAX_CODE_SIZE) {
- codeSize++;
+ if (getCodeSize() < MAX_CODE_SIZE) {
+ incrementCodeSize();
} else {
throw new IOException("Attempt to increase code size beyond maximum");
}
} else if (subCode == 2) {
partialClear();
- tableSize = clearCode + 1;
+ setTableSize(getClearCode() + 1);
} else {
throw new IOException("Invalid clear code subcode " + subCode);
}
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
index c53ce9f..169f088 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
@@ -1243,7 +1243,7 @@
int extraStart = CFH_FILENAME_OFFSET + nameLen;
System.arraycopy(extra, 0, buf, extraStart, extra.length);
- int commentStart = extraStart + commentLen;
+ int commentStart = extraStart + extra.length;
// file comment
System.arraycopy(commentB.array(), commentB.arrayOffset(), buf, commentStart, commentLen);
diff --git a/src/main/java/org/apache/commons/compress/compressors/lzw/LZWInputStream.java b/src/main/java/org/apache/commons/compress/compressors/lzw/LZWInputStream.java
index 6900b7c..dc9212d 100644
--- a/src/main/java/org/apache/commons/compress/compressors/lzw/LZWInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/lzw/LZWInputStream.java
@@ -34,16 +34,19 @@
* @since 1.10
*/
public abstract class LZWInputStream extends CompressorInputStream {
+ protected static final int DEFAULT_CODE_SIZE = 9;
+ protected static final int UNUSED_PREFIX = -1;
+
private final byte[] oneByte = new byte[1];
protected final BitInputStream in;
- protected int clearCode = -1;
- protected int codeSize = 9;
- protected byte previousCodeFirstChar;
- protected int previousCode = -1;
- protected int tableSize = 0;
- protected int[] prefixes;
- protected byte[] characters;
+ private int clearCode = -1;
+ private int codeSize = DEFAULT_CODE_SIZE;
+ private byte previousCodeFirstChar;
+ private int previousCode = UNUSED_PREFIX;
+ private int tableSize;
+ private int[] prefixes;
+ private byte[] characters;
private byte[] outputStack;
private int outputStackLocation;
@@ -178,4 +181,60 @@
}
return 0;
}
+
+ protected int getCodeSize() {
+ return codeSize;
+ }
+
+ protected void resetCodeSize() {
+ this.codeSize = DEFAULT_CODE_SIZE;
+ }
+
+ protected void incrementCodeSize() {
+ codeSize++;
+ }
+
+ protected int getPreviousCode() {
+ return previousCode;
+ }
+
+ protected byte getPreviousCodeFirstChar() {
+ return previousCodeFirstChar;
+ }
+
+ protected void resetPreviousCode() {
+ this.previousCode = -1;
+ }
+
+ protected int getPrefix(int offset) {
+ return prefixes[offset];
+ }
+
+ protected void setPrefix(int offset, int value) {
+ prefixes[offset] = value;
+ }
+
+ protected int getPrefixesLength() {
+ return prefixes.length;
+ }
+
+ protected int getClearCode() {
+ return clearCode;
+ }
+
+ protected int getTableSize() {
+ return tableSize;
+ }
+
+ protected void setTableSize(int newSize) {
+ tableSize = newSize;
+ }
+
+ protected void setCharacter(int offset, byte value) {
+ characters[offset] = value;
+ }
+
+ protected byte getCharacter(int offset) {
+ return characters[offset];
+ }
}
diff --git a/src/main/java/org/apache/commons/compress/compressors/z/ZCompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/z/ZCompressorInputStream.java
index 1bb65b5..e21df06 100644
--- a/src/main/java/org/apache/commons/compress/compressors/z/ZCompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/z/ZCompressorInputStream.java
@@ -49,17 +49,14 @@
blockMode = (thirdByte & BLOCK_MODE_MASK) != 0;
maxCodeSize = thirdByte & MAX_CODE_SIZE_MASK;
if (blockMode) {
- setClearCode(codeSize);
+ setClearCode(DEFAULT_CODE_SIZE);
}
initializeTables(maxCodeSize);
clearEntries();
}
private void clearEntries() {
- tableSize = 1 << 8;
- if (blockMode) {
- tableSize++;
- }
+ setTableSize((1 << 8) + (blockMode ? 1 : 0));
}
/**
@@ -100,11 +97,11 @@
*/
@Override
protected int addEntry(int previousCode, byte character) throws IOException {
- final int maxTableSize = 1 << codeSize;
+ final int maxTableSize = 1 << getCodeSize();
int r = addEntry(previousCode, character, maxTableSize);
- if (tableSize == maxTableSize && codeSize < maxCodeSize) {
+ if (getTableSize() == maxTableSize && getCodeSize() < maxCodeSize) {
reAlignReading();
- codeSize++;
+ incrementCodeSize();
}
return r;
}
@@ -132,19 +129,19 @@
final int code = readNextCode();
if (code < 0) {
return -1;
- } else if (blockMode && code == clearCode) {
+ } else if (blockMode && code == getClearCode()) {
clearEntries();
reAlignReading();
- codeSize = 9;
- previousCode = -1;
+ resetCodeSize();
+ resetPreviousCode();
return 0;
} else {
boolean addedUnfinishedEntry = false;
- if (code == tableSize) {
+ if (code == getTableSize()) {
addRepeatOfPreviousCode();
addedUnfinishedEntry = true;
- } else if (code > tableSize) {
- throw new IOException(String.format("Invalid %d bit code 0x%x", codeSize, code));
+ } else if (code > getTableSize()) {
+ throw new IOException(String.format("Invalid %d bit code 0x%x", getCodeSize(), code));
}
return expandCodeToOutputStack(code, addedUnfinishedEntry);
}