< prev index next >
src/java.base/share/classes/java/util/jar/Attributes.java
Print this page
rev 51517 : 8205525: Improve exception messages during manifest parsing of jar archives
@@ -24,18 +24,24 @@
*/
package java.util.jar;
import java.io.DataOutputStream;
+import java.io.File;
import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Security;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import sun.security.util.SecurityProperties;
+
import sun.util.logging.PlatformLogger;
/**
* The Attributes class maps Manifest attribute names to associated string
* values. Valid attribute names are case-insensitive, are restricted to
@@ -58,10 +64,13 @@
/**
* The attribute name-value mappings.
*/
protected Map<Object,Object> map;
+ private static final boolean jarPathInExceptionText =
+ SecurityProperties.includedInExceptions("jarPath");
+
/**
* Constructs a new, empty Attributes object with default size.
*/
public Attributes() {
this(11);
@@ -367,21 +376,29 @@
/*
* Reads attributes from the specified input stream.
* XXX Need to handle UTF8 values.
*/
- @SuppressWarnings("deprecation")
void read(Manifest.FastInputStream is, byte[] lbuf) throws IOException {
+ read(is, lbuf, null, 0);
+ }
+
+ @SuppressWarnings("deprecation")
+ int read(Manifest.FastInputStream is, byte[] lbuf, String filename, int offset) throws IOException {
String name = null, value;
byte[] lastline = null;
+ int lineNumber = offset;
int len;
while ((len = is.readLine(lbuf)) != -1) {
boolean lineContinued = false;
byte c = lbuf[--len];
+ lineNumber++;
+
if (c != '\n' && c != '\r') {
- throw new IOException("line too long");
+ throw new IOException("line too long ("
+ + getErrorPosition(filename, lineNumber) + ")");
}
if (len > 0 && lbuf[len-1] == '\r') {
--len;
}
if (len == 0) {
@@ -389,11 +406,12 @@
}
int i = 0;
if (lbuf[0] == ' ') {
// continuation of previous line
if (name == null) {
- throw new IOException("misplaced continuation line");
+ throw new IOException("misplaced continuation line ("
+ + getErrorPosition(filename, lineNumber) + ")");
}
lineContinued = true;
byte[] buf = new byte[lastline.length + len - 1];
System.arraycopy(lastline, 0, buf, 0, lastline.length);
System.arraycopy(lbuf, 1, buf, lastline.length, len - 1);
@@ -404,15 +422,17 @@
value = new String(buf, 0, buf.length, "UTF8");
lastline = null;
} else {
while (lbuf[i++] != ':') {
if (i >= len) {
- throw new IOException("invalid header field");
+ throw new IOException("invalid header field ("
+ + getErrorPosition(filename, lineNumber) + ")");
}
}
if (lbuf[i++] != ' ') {
- throw new IOException("invalid header field");
+ throw new IOException("invalid header field ("
+ + getErrorPosition(filename, lineNumber) + ")");
}
name = new String(lbuf, 0, 0, i - 2);
if (is.peek() == ' ') {
lastline = new byte[len - i];
System.arraycopy(lbuf, i, lastline, 0, len - i);
@@ -431,13 +451,28 @@
+ "individual sections in both your\n"
+ "manifest and in the META-INF/MANIFEST.MF "
+ "entry in the jar file.");
}
} catch (IllegalArgumentException e) {
- throw new IOException("invalid header field name: " + name);
+ throw new IOException("invalid header field name: " + name
+ + " (" + getErrorPosition(filename, lineNumber) + ")");
+ }
+ }
+ return lineNumber;
}
+
+ static String getErrorPosition(String filename, final int lineNumber) {
+ if (filename == null || !jarPathInExceptionText) {
+ return "line " + lineNumber;
+ }
+
+ final File file = new File(filename);
+ return AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return file.getAbsolutePath() + ":" + lineNumber;
}
+ });
}
/**
* The Attributes.Name class represents an attribute name stored in
* this Map. Valid attribute names are case-insensitive, are restricted
< prev index next >