This commit is contained in:
Henry Jen 2019-07-17 00:21:02 +00:00
commit f860f94696
25 changed files with 534 additions and 156 deletions

View file

@ -25,8 +25,8 @@
package java.lang;
import java.io.*;
import java.util.*;
import java.io.*;
import java.util.*;
/**
* The {@code Throwable} class is the superclass of all errors and
@ -904,24 +904,36 @@ public class Throwable implements Serializable {
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject(); // read in all fields
if (suppressedExceptions != null) {
List<Throwable> suppressed = null;
if (suppressedExceptions.isEmpty()) {
// Use the sentinel for a zero-length list
suppressed = SUPPRESSED_SENTINEL;
} else { // Copy Throwables to new list
suppressed = new ArrayList<>(1);
for (Throwable t : suppressedExceptions) {
// Set suppressed exceptions and stack trace elements fields
// to marker values until the contents from the serial stream
// are validated.
List<Throwable> candidateSuppressedExceptions = suppressedExceptions;
suppressedExceptions = SUPPRESSED_SENTINEL;
StackTraceElement[] candidateStackTrace = stackTrace;
stackTrace = UNASSIGNED_STACK.clone();
if (candidateSuppressedExceptions != null) {
int suppressedSize = validateSuppressedExceptionsList(candidateSuppressedExceptions);
if (suppressedSize > 0) { // Copy valid Throwables to new list
var suppList = new ArrayList<Throwable>(Math.min(100, suppressedSize));
for (Throwable t : candidateSuppressedExceptions) {
// Enforce constraints on suppressed exceptions in
// case of corrupt or malicious stream.
Objects.requireNonNull(t, NULL_CAUSE_MESSAGE);
if (t == this)
throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
suppressed.add(t);
suppList.add(t);
}
// If there are any invalid suppressed exceptions,
// implicitly use the sentinel value assigned earlier.
suppressedExceptions = suppList;
}
suppressedExceptions = suppressed;
} // else a null suppressedExceptions field remains null
} else {
suppressedExceptions = null;
}
/*
* For zero-length stack traces, use a clone of
@ -932,24 +944,41 @@ public class Throwable implements Serializable {
* the stackTrace needs to be constructed from the information
* in backtrace.
*/
if (stackTrace != null) {
if (stackTrace.length == 0) {
stackTrace = UNASSIGNED_STACK.clone();
} else if (stackTrace.length == 1 &&
if (candidateStackTrace != null) {
// Work from a clone of the candidateStackTrace to ensure
// consistency of checks.
candidateStackTrace = candidateStackTrace.clone();
if (candidateStackTrace.length >= 1) {
if (candidateStackTrace.length == 1 &&
// Check for the marker of an immutable stack trace
SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
stackTrace = null;
} else { // Verify stack trace elements are non-null.
for(StackTraceElement ste : stackTrace) {
Objects.requireNonNull(ste, "null StackTraceElement in serial stream.");
SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(candidateStackTrace[0])) {
stackTrace = null;
} else { // Verify stack trace elements are non-null.
for (StackTraceElement ste : candidateStackTrace) {
Objects.requireNonNull(ste, "null StackTraceElement in serial stream.");
}
stackTrace = candidateStackTrace;
}
}
}
// A null stackTrace field in the serial form can result from
// an exception serialized without that field in older JDK
// releases; treat such exceptions as having empty stack
// traces by leaving stackTrace assigned to a clone of
// UNASSIGNED_STACK.
}
private int validateSuppressedExceptionsList(List<Throwable> deserSuppressedExceptions)
throws IOException {
if (!Object.class.getModule().
equals(deserSuppressedExceptions.getClass().getModule())) {
throw new StreamCorruptedException("List implementation not in base module.");
} else {
// A null stackTrace field in the serial form can result
// from an exception serialized without that field in
// older JDK releases; treat such exceptions as having
// empty stack traces.
stackTrace = UNASSIGNED_STACK.clone();
int size = deserSuppressedExceptions.size();
if (size < 0) {
throw new StreamCorruptedException("Negative list size reported.");
}
return size;
}
}

View file

@ -45,6 +45,7 @@ import java.util.ServiceLoader;
import jdk.internal.access.JavaNetURLAccess;
import jdk.internal.access.SharedSecrets;
import sun.net.util.IPAddressUtil;
import sun.security.util.SecurityConstants;
import sun.security.action.GetPropertyAction;
@ -466,13 +467,19 @@ public final class URL implements java.io.Serializable {
this.file = path;
}
// Note: we don't do validation of the URL here. Too risky to change
// Note: we don't do full validation of the URL here. Too risky to change
// right now, but worth considering for future reference. -br
if (handler == null &&
(handler = getURLStreamHandler(protocol)) == null) {
throw new MalformedURLException("unknown protocol: " + protocol);
}
this.handler = handler;
if (host != null && isBuiltinStreamHandler(handler)) {
String s = IPAddressUtil.checkExternalForm(this);
if (s != null) {
throw new MalformedURLException(s);
}
}
}
/**
@ -1038,7 +1045,12 @@ public final class URL implements java.io.Serializable {
* @since 1.5
*/
public URI toURI() throws URISyntaxException {
return new URI (toString());
URI uri = new URI(toString());
if (authority != null && isBuiltinStreamHandler(handler)) {
String s = IPAddressUtil.checkAuthority(this);
if (s != null) throw new URISyntaxException(authority, s);
}
return uri;
}
/**
@ -1635,6 +1647,10 @@ public final class URL implements java.io.Serializable {
return replacementURL;
}
boolean isBuiltinStreamHandler(URLStreamHandler handler) {
return isBuiltinStreamHandler(handler.getClass().getName());
}
private boolean isBuiltinStreamHandler(String handlerClassName) {
return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
}

View file

@ -516,12 +516,15 @@ public abstract class URLStreamHandler {
* different from this one
* @since 1.3
*/
protected void setURL(URL u, String protocol, String host, int port,
protected void setURL(URL u, String protocol, String host, int port,
String authority, String userInfo, String path,
String query, String ref) {
if (this != u.handler) {
throw new SecurityException("handler for url different from " +
"this handler");
} else if (host != null && u.isBuiltinStreamHandler(this)) {
String s = IPAddressUtil.checkHostString(host);
if (s != null) throw new IllegalArgumentException(s);
}
// ensure that no one can reset the protocol on a given URL.
u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -445,7 +445,8 @@ public final class AccessController {
throw new NullPointerException("null permissions parameter");
}
Class<?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(null,
DomainCombiner dc = (context == null) ? null : context.getCombiner();
return AccessController.doPrivileged(action, createWrapper(dc,
caller, parent, context, perms));
}
@ -860,7 +861,8 @@ public final class AccessController {
throw new NullPointerException("null permissions parameter");
}
Class<?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms));
DomainCombiner dc = (context == null) ? null : context.getCombiner();
return AccessController.doPrivileged(action, createWrapper(dc, caller, parent, context, perms));
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package java.util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
@ -39,6 +40,7 @@ import java.util.function.UnaryOperator;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import jdk.internal.access.SharedSecrets;
/**
* This class consists exclusively of static methods that operate on or return
@ -5163,6 +5165,11 @@ public class Collections {
public Spliterator<E> spliterator() {
return stream().spliterator();
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(ois, Object[].class, n);
}
}
/**