From 7978d50edb9c4da0b8f4076412f092418da6e372 Mon Sep 17 00:00:00 2001 From: Ficus Kirkpatrick Date: Thu, 23 Sep 2010 22:57:05 -0700 Subject: [PATCH] Add a workaround for a platform JAR parsing bug. The java.util.jar implementation through Android 1.6 has a bug where if the signature file in META-INF is a multiple of 1024 bytes, it will throw an IOException attempting to read it. If signapk would produce a CERT.SF in a multiple of 1024 bytes, add an extra CRLF to the end of the file. Bug: 3019677 Change-Id: I23d4a36e12e224be600d3ac39379b5b5a022a628 --- tools/signapk/SignApk.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tools/signapk/SignApk.java b/tools/signapk/SignApk.java index 3244a4902..c4d73c8cf 100644 --- a/tools/signapk/SignApk.java +++ b/tools/signapk/SignApk.java @@ -220,10 +220,12 @@ class SignApk { /** Write to another stream and also feed it to the Signature object. */ private static class SignatureOutputStream extends FilterOutputStream { private Signature mSignature; + private int mCount; public SignatureOutputStream(OutputStream out, Signature sig) { super(out); mSignature = sig; + mCount = 0; } @Override @@ -234,6 +236,7 @@ class SignApk { throw new IOException("SignatureException: " + e); } super.write(b); + mCount++; } @Override @@ -244,11 +247,16 @@ class SignApk { throw new IOException("SignatureException: " + e); } super.write(b, off, len); + mCount += len; + } + + public int size() { + return mCount; } } /** Write a .SF file with a digest of the specified manifest. */ - private static void writeSignatureFile(Manifest manifest, OutputStream out) + private static void writeSignatureFile(Manifest manifest, SignatureOutputStream out) throws IOException, GeneralSecurityException { Manifest sf = new Manifest(); Attributes main = sf.getMainAttributes(); @@ -282,6 +290,15 @@ class SignApk { } sf.write(out); + + // A bug in the java.util.jar implementation of Android platforms + // up to version 1.6 will cause a spurious IOException to be thrown + // if the length of the signature file is a multiple of 1024 bytes. + // As a workaround, add an extra CRLF in this case. + if ((out.size() % 1024) == 0) { + out.write('\r'); + out.write('\n'); + } } /** Write a .RSA file with a digital signature. */