OSDN Git Service

Add a workaround for a platform JAR parsing bug.
authorFicus Kirkpatrick <ficus@android.com>
Fri, 24 Sep 2010 05:57:05 +0000 (22:57 -0700)
committerFicus Kirkpatrick <ficus@android.com>
Fri, 24 Sep 2010 17:24:53 +0000 (10:24 -0700)
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

index 3244a49..c4d73c8 100644 (file)
@@ -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. */