Index: chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkVerifySignature.java |
diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkVerifySignature.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkVerifySignature.java |
index 7ae1de9361b14ddbf533716f1a20b893ebc53c5f..bed1a2e78c5ce25f503f3534bed3eb0d166f5892 100644 |
--- a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkVerifySignature.java |
+++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkVerifySignature.java |
@@ -14,6 +14,7 @@ import java.security.PublicKey; |
import java.security.Signature; |
import java.util.ArrayList; |
import java.util.Collections; |
+import java.util.Comparator; |
import java.util.regex.Matcher; |
import java.util.regex.Pattern; |
@@ -126,6 +127,14 @@ public class WebApkVerifySignature { |
return mFilename.compareTo(o.mFilename); |
} |
+ /** Comparator for sorting the list by position ascending. */ |
+ public static Comparator<Block> positionComparator = new Comparator<Block>() { |
+ @Override |
+ public int compare(Block b1, Block b2) { |
+ return b1.mPosition - b2.mPosition; |
+ } |
+ }; |
+ |
@Override |
public boolean equals(Object o) { |
if (!(o instanceof Block)) return false; |
@@ -324,15 +333,17 @@ public class WebApkVerifySignature { |
return ERROR_BAD_BLANK_SPACE; |
} |
- boolean hasBlockAtStart = false; |
- long positionOfLastByteOfLastBlock = 0; |
+ // We need blocks to be sorted by position at this point. |
+ Collections.sort(mBlocks, Block.positionComparator); |
+ int lastByte = 0; |
// Read the 'local file header' block to the size of the header in bytes. |
for (Block block : mBlocks) { |
- seek(block.mPosition); |
- if (block.mPosition == 0) { |
- hasBlockAtStart = true; |
+ if (block.mPosition != lastByte) { |
+ return ERROR_BAD_BLANK_SPACE; |
} |
+ |
+ seek(block.mPosition); |
int signature = read4(); |
if (signature != LFH_SIG) { |
Log.d(TAG, "LFH Signature missing"); |
@@ -353,7 +364,7 @@ public class WebApkVerifySignature { |
block.mHeaderSize = |
(mBuffer.position() - block.mPosition) + fileNameLength + extraFieldLength; |
- int lastByte = block.mPosition + block.mHeaderSize + block.mCompressedSize; |
+ lastByte = block.mPosition + block.mHeaderSize + block.mCompressedSize; |
if ((flags & 0x8) != 0) { |
seek(lastByte); |
if (read4() == DATA_DESCRIPTOR_SIG) { |
@@ -366,20 +377,14 @@ public class WebApkVerifySignature { |
lastByte += 12; |
} |
} |
- if (lastByte > positionOfLastByteOfLastBlock) { |
- positionOfLastByteOfLastBlock = lastByte; |
- } |
- } |
- if (!hasBlockAtStart) { |
- return ERROR_BAD_BLANK_SPACE; |
} |
- if (positionOfLastByteOfLastBlock != mCentralDirOffset) { |
+ if (lastByte != mCentralDirOffset) { |
seek(mCentralDirOffset - V2_SIGNING_MAGIC.length()); |
String magic = readString(V2_SIGNING_MAGIC.length()); |
if (V2_SIGNING_MAGIC.equals(magic)) { |
// Only if we have a v2 signature do we allow medium sized gap between the last |
// block and the start of the central directory. |
- if (mCentralDirOffset - positionOfLastByteOfLastBlock > MAX_V2_SIGNING_BLOCK_SIZE) { |
+ if (mCentralDirOffset - lastByte > MAX_V2_SIGNING_BLOCK_SIZE) { |
return ERROR_BAD_V2_SIGNING_BLOCK; |
} |
} else { |