| 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 {
|
|
|