< 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,41 ****
--- 24,47 ----
*/
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,67 ****
--- 64,76 ----
/**
* 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,387 ****
/*
* Reads attributes from the specified input stream.
* XXX Need to handle UTF8 values.
*/
- @SuppressWarnings("deprecation")
void read(Manifest.FastInputStream is, byte[] lbuf) throws IOException {
String name = null, value;
byte[] lastline = null;
int len;
while ((len = is.readLine(lbuf)) != -1) {
boolean lineContinued = false;
byte c = lbuf[--len];
if (c != '\n' && c != '\r') {
! throw new IOException("line too long");
}
if (len > 0 && lbuf[len-1] == '\r') {
--len;
}
if (len == 0) {
--- 376,404 ----
/*
* Reads attributes from the specified input stream.
* XXX Need to handle UTF8 values.
*/
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 ("
! + getErrorPosition(filename, lineNumber) + ")");
}
if (len > 0 && lbuf[len-1] == '\r') {
--len;
}
if (len == 0) {
*** 389,399 ****
}
int i = 0;
if (lbuf[0] == ' ') {
// continuation of previous line
if (name == null) {
! throw new IOException("misplaced continuation line");
}
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);
--- 406,417 ----
}
int i = 0;
if (lbuf[0] == ' ') {
// continuation of previous line
if (name == null) {
! 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,418 ****
value = new String(buf, 0, buf.length, "UTF8");
lastline = null;
} else {
while (lbuf[i++] != ':') {
if (i >= len) {
! throw new IOException("invalid header field");
}
}
if (lbuf[i++] != ' ') {
! throw new IOException("invalid header field");
}
name = new String(lbuf, 0, 0, i - 2);
if (is.peek() == ' ') {
lastline = new byte[len - i];
System.arraycopy(lbuf, i, lastline, 0, len - i);
--- 422,438 ----
value = new String(buf, 0, buf.length, "UTF8");
lastline = null;
} else {
while (lbuf[i++] != ':') {
if (i >= len) {
! throw new IOException("invalid header field ("
! + getErrorPosition(filename, lineNumber) + ")");
}
}
if (lbuf[i++] != ' ') {
! 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,443 ****
+ "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);
}
}
}
/**
* The Attributes.Name class represents an attribute name stored in
* this Map. Valid attribute names are case-insensitive, are restricted
--- 451,478 ----
+ "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
! + " (" + 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 >