提交 d6f64717 编写于 作者: A andrew

8212328: Exceptional throw cases

Reviewed-by: smarks, rriggs, igerasim, ahgross, skoivu, andrew
Contributed-by: NDavid Alvarez <alvdavi@amazon.com>
上级 caddb42f
/* /*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
*/ */
package java.lang; 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 * The {@code Throwable} class is the superclass of all errors and
...@@ -912,25 +913,37 @@ public class Throwable implements Serializable { ...@@ -912,25 +913,37 @@ public class Throwable implements Serializable {
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
s.defaultReadObject(); // read in all fields s.defaultReadObject(); // read in all fields
if (suppressedExceptions != null) {
List<Throwable> suppressed = null; // Set suppressed exceptions and stack trace elements fields
if (suppressedExceptions.isEmpty()) { // to marker values until the contents from the serial stream
// Use the sentinel for a zero-length list // are validated.
suppressed = SUPPRESSED_SENTINEL; List<Throwable> candidateSuppressedExceptions = suppressedExceptions;
} else { // Copy Throwables to new list suppressedExceptions = SUPPRESSED_SENTINEL;
suppressed = new ArrayList<>(1);
for (Throwable t : suppressedExceptions) { StackTraceElement[] candidateStackTrace = stackTrace;
stackTrace = UNASSIGNED_STACK.clone();
if (candidateSuppressedExceptions != null) {
int suppressedSize = validateSuppressedExceptionsList(candidateSuppressedExceptions);
if (suppressedSize > 0) { // Copy valid Throwables to new list
List<Throwable> suppList = new ArrayList<Throwable>(Math.min(100, suppressedSize));
for (Throwable t : candidateSuppressedExceptions) {
// Enforce constraints on suppressed exceptions in // Enforce constraints on suppressed exceptions in
// case of corrupt or malicious stream. // case of corrupt or malicious stream.
if (t == null) if (t == null)
throw new NullPointerException(NULL_CAUSE_MESSAGE); throw new NullPointerException(NULL_CAUSE_MESSAGE);
if (t == this) if (t == this)
throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE); 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 {
} // else a null suppressedExceptions field remains null suppressedExceptions = null;
}
/* /*
* For zero-length stack traces, use a clone of * For zero-length stack traces, use a clone of
...@@ -941,25 +954,41 @@ public class Throwable implements Serializable { ...@@ -941,25 +954,41 @@ public class Throwable implements Serializable {
* the stackTrace needs to be constructed from the information * the stackTrace needs to be constructed from the information
* in backtrace. * in backtrace.
*/ */
if (stackTrace != null) { if (candidateStackTrace != null) {
if (stackTrace.length == 0) { // Work from a clone of the candidateStackTrace to ensure
stackTrace = UNASSIGNED_STACK.clone(); // consistency of checks.
} else if (stackTrace.length == 1 && candidateStackTrace = candidateStackTrace.clone();
if (candidateStackTrace.length >= 1) {
if (candidateStackTrace.length == 1 &&
// Check for the marker of an immutable stack trace // Check for the marker of an immutable stack trace
SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) { SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(candidateStackTrace[0])) {
stackTrace = null; stackTrace = null;
} else { // Verify stack trace elements are non-null. } else { // Verify stack trace elements are non-null.
for(StackTraceElement ste : stackTrace) { for (StackTraceElement ste : candidateStackTrace) {
if (ste == null) if (ste == null)
throw new NullPointerException("null StackTraceElement in serial stream. "); throw new NullPointerException("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.getClassLoader() != deserSuppressedExceptions.getClass().getClassLoader()) {
throw new StreamCorruptedException("List implementation not on the bootclasspath.");
} else { } else {
// A null stackTrace field in the serial form can result int size = deserSuppressedExceptions.size();
// from an exception serialized without that field in if (size < 0) {
// older JDK releases; treat such exceptions as having throw new StreamCorruptedException("Negative list size reported.");
// empty stack traces. }
stackTrace = UNASSIGNED_STACK.clone(); return size;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册