src/share/classes/sun/security/tools/JarSigner.java
Print this page
rev 352 : 6948909: Jarsigner removes MANIFEST.MF info for badly packages jar's
Reviewed-by: mullan, xuelei
@@ -949,19 +949,26 @@
* generated one. (This may invalidate existing signatures!)
*/
BASE64Encoder encoder = new JarBASE64Encoder();
Vector<ZipEntry> mfFiles = new Vector<ZipEntry>();
+ boolean wasSigned = false;
+
for (Enumeration<? extends ZipEntry> enum_=zipFile.entries();
enum_.hasMoreElements();) {
ZipEntry ze = enum_.nextElement();
if (ze.getName().startsWith(META_INF)) {
// Store META-INF files in vector, so they can be written
// out first
mfFiles.addElement(ze);
+ if (SignatureFileVerifier.isBlockOrSF(
+ ze.getName().toUpperCase(Locale.ENGLISH))) {
+ wasSigned = true;
+ }
+
if (signatureRelated(ze.getName())) {
// ignore signature-related and manifest files
continue;
}
}
@@ -985,10 +992,11 @@
// Recalculate the manifest raw bytes if necessary
if (mfModified) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
manifest.write(baos);
+ if (wasSigned) {
byte[] newBytes = baos.toByteArray();
if (mfRawBytes != null
&& oldAttr.equals(manifest.getMainAttributes())) {
/*
@@ -1016,10 +1024,13 @@
newBytes.length - newPos);
newBytes = lastBytes;
}
}
mfRawBytes = newBytes;
+ } else {
+ mfRawBytes = baos.toByteArray();
+ }
}
// Write out the manifest
if (mfModified) {
// manifest file has new length
@@ -1231,27 +1242,35 @@
// error(rb.getString("unable to sign jar: ")+ioe, ioe);
// }
}
/**
- * Find the position of an empty line inside bs
+ * Find the length of header inside bs. The header is a multiple (>=0)
+ * lines of attributes plus an empty line. The empty line is included
+ * in the header.
*/
private int findHeaderEnd(byte[] bs) {
- // An empty line can be at the beginning...
- if (bs.length > 1 && bs[0] == '\r' && bs[1] == '\n') {
- return 0;
- }
- // ... or after another line
- for (int i=0; i<bs.length-3; i++) {
- if (bs[i] == '\r' && bs[i+1] == '\n' &&
- bs[i+2] == '\r' && bs[i+3] == '\n') {
- return i;
+ // Initial state true to deal with empty header
+ boolean newline = true; // just met a newline
+ int len = bs.length;
+ for (int i=0; i<len; i++) {
+ switch (bs[i]) {
+ case '\r':
+ if (i < len - 1 && bs[i+1] == '\n') i++;
+ // fallthrough
+ case '\n':
+ if (newline) return i+1; //+1 to get length
+ newline = true;
+ break;
+ default:
+ newline = false;
}
}
- // If header end is not found, return 0,
- // which means no behavior change.
- return 0;
+ // If header end is not found, it means the MANIFEST.MF has only
+ // the main attributes section and it does not end with 2 newlines.
+ // Returns the whole length so that it can be completely replaced.
+ return len;
}
/**
* signature-related files include:
* . META-INF/MANIFEST.MF