This commit is contained in:
Vinnie Ryan 2013-04-17 02:53:02 -07:00
commit 74d720c7b5
309 changed files with 11139 additions and 2283 deletions

View File

@ -48,7 +48,6 @@ FILES_c = \
Proxy.c \ Proxy.c \
RandomAccessFile.c \ RandomAccessFile.c \
RandomAccessFile_md.c \ RandomAccessFile_md.c \
ResourceBundle.c \
Runtime.c \ Runtime.c \
SecurityManager.c \ SecurityManager.c \
Shutdown.c \ Shutdown.c \

View File

@ -134,7 +134,6 @@ SUNWprivate_1.1 {
Java_java_lang_ClassLoader_00024NativeLibrary_load; Java_java_lang_ClassLoader_00024NativeLibrary_load;
Java_java_lang_ClassLoader_00024NativeLibrary_unload; Java_java_lang_ClassLoader_00024NativeLibrary_unload;
Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib; Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib;
Java_java_lang_ClassLoader_getCaller;
Java_java_lang_ClassLoader_registerNatives; Java_java_lang_ClassLoader_registerNatives;
Java_java_lang_Compiler_registerNatives; Java_java_lang_Compiler_registerNatives;
Java_java_lang_Double_longBitsToDouble; Java_java_lang_Double_longBitsToDouble;
@ -233,7 +232,6 @@ SUNWprivate_1.1 {
Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2; Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2;
Java_java_security_AccessController_getStackAccessControlContext; Java_java_security_AccessController_getStackAccessControlContext;
Java_java_security_AccessController_getInheritedAccessControlContext; Java_java_security_AccessController_getInheritedAccessControlContext;
Java_java_util_ResourceBundle_getClassContext;
Java_java_util_TimeZone_getSystemTimeZoneID; Java_java_util_TimeZone_getSystemTimeZoneID;
Java_java_util_TimeZone_getSystemGMTOffsetID; Java_java_util_TimeZone_getSystemGMTOffsetID;
Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8; Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8;

View File

@ -73,7 +73,6 @@ text: .text%writeBytes;
# Test Sleep # Test Sleep
# Test IntToString # Test IntToString
# Test LoadToolkit # Test LoadToolkit
text: .text%Java_java_util_ResourceBundle_getClassContext;
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2; text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
text: .text%JNU_GetEnv; text: .text%JNU_GetEnv;
text: .text%Java_java_io_UnixFileSystem_checkAccess; text: .text%Java_java_io_UnixFileSystem_checkAccess;

View File

@ -78,7 +78,6 @@ text: .text%writeBytes;
# Test Sleep # Test Sleep
# Test IntToString # Test IntToString
# Test LoadToolkit # Test LoadToolkit
text: .text%Java_java_util_ResourceBundle_getClassContext;
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2; text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
text: .text%JNU_GetEnv; text: .text%JNU_GetEnv;
text: .text%Java_java_io_UnixFileSystem_checkAccess; text: .text%Java_java_io_UnixFileSystem_checkAccess;

View File

@ -74,7 +74,6 @@ text: .text%writeBytes;
# Test Sleep # Test Sleep
# Test IntToString # Test IntToString
# Test LoadToolkit # Test LoadToolkit
text: .text%Java_java_util_ResourceBundle_getClassContext;
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2; text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
text: .text%JNU_GetEnv; text: .text%JNU_GetEnv;
text: .text%Java_java_io_UnixFileSystem_checkAccess; text: .text%Java_java_io_UnixFileSystem_checkAccess;

View File

@ -106,7 +106,21 @@ FILES_cpp_shared = \
OpenTypeLayoutEngine.cpp \ OpenTypeLayoutEngine.cpp \
ThaiLayoutEngine.cpp \ ThaiLayoutEngine.cpp \
ScriptAndLanguageTags.cpp \ ScriptAndLanguageTags.cpp \
FontInstanceAdapter.cpp FontInstanceAdapter.cpp \
ContextualGlyphInsertionProc2.cpp \
ContextualGlyphSubstProc2.cpp \
GXLayoutEngine2.cpp \
IndicRearrangementProcessor2.cpp \
LigatureSubstProc2.cpp \
MorphTables2.cpp \
NonContextualGlyphSubstProc2.cpp \
SegmentArrayProcessor2.cpp \
SegmentSingleProcessor2.cpp \
SimpleArrayProcessor2.cpp \
SingleTableProcessor2.cpp \
StateTableProcessor2.cpp \
SubtableProcessor2.cpp \
TrimmedArrayProcessor2.cpp
ifeq ($(PLATFORM),windows) ifeq ($(PLATFORM),windows)

View File

@ -134,7 +134,6 @@ SUNWprivate_1.1 {
Java_java_lang_ClassLoader_00024NativeLibrary_load; Java_java_lang_ClassLoader_00024NativeLibrary_load;
Java_java_lang_ClassLoader_00024NativeLibrary_unload; Java_java_lang_ClassLoader_00024NativeLibrary_unload;
Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib; Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib;
Java_java_lang_ClassLoader_getCaller;
Java_java_lang_ClassLoader_registerNatives; Java_java_lang_ClassLoader_registerNatives;
Java_java_lang_Compiler_registerNatives; Java_java_lang_Compiler_registerNatives;
Java_java_lang_Double_longBitsToDouble; Java_java_lang_Double_longBitsToDouble;
@ -233,7 +232,6 @@ SUNWprivate_1.1 {
Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2; Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2;
Java_java_security_AccessController_getStackAccessControlContext; Java_java_security_AccessController_getStackAccessControlContext;
Java_java_security_AccessController_getInheritedAccessControlContext; Java_java_security_AccessController_getInheritedAccessControlContext;
Java_java_util_ResourceBundle_getClassContext;
Java_java_util_TimeZone_getSystemTimeZoneID; Java_java_util_TimeZone_getSystemTimeZoneID;
Java_java_util_TimeZone_getSystemGMTOffsetID; Java_java_util_TimeZone_getSystemGMTOffsetID;
Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8; Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8;

View File

@ -78,7 +78,6 @@ text: .text%writeBytes;
# Test Sleep # Test Sleep
# Test IntToString # Test IntToString
# Test LoadToolkit # Test LoadToolkit
text: .text%Java_java_util_ResourceBundle_getClassContext;
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2; text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
text: .text%JNU_GetEnv; text: .text%JNU_GetEnv;
text: .text%Java_java_io_UnixFileSystem_checkAccess; text: .text%Java_java_io_UnixFileSystem_checkAccess;

View File

@ -74,7 +74,6 @@ text: .text%writeBytes;
# Test Sleep # Test Sleep
# Test IntToString # Test IntToString
# Test LoadToolkit # Test LoadToolkit
text: .text%Java_java_util_ResourceBundle_getClassContext;
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2; text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
text: .text%JNU_GetEnv; text: .text%JNU_GetEnv;
text: .text%Java_java_io_UnixFileSystem_checkAccess; text: .text%Java_java_io_UnixFileSystem_checkAccess;

View File

@ -73,7 +73,6 @@ text: .text%writeBytes;
# Test Sleep # Test Sleep
# Test IntToString # Test IntToString
# Test LoadToolkit # Test LoadToolkit
text: .text%Java_java_util_ResourceBundle_getClassContext;
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2; text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
text: .text%JNU_GetEnv; text: .text%JNU_GetEnv;
text: .text%Java_java_io_UnixFileSystem_checkAccess; text: .text%Java_java_io_UnixFileSystem_checkAccess;

View File

@ -170,7 +170,7 @@ public class LWWindowPeer
setTitle(((Dialog) getTarget()).getTitle()); setTitle(((Dialog) getTarget()).getTitle());
} }
setAlwaysOnTop(getTarget().isAlwaysOnTop()); updateAlwaysOnTopState();
updateMinimumSize(); updateMinimumSize();
final Shape shape = getTarget().getShape(); final Shape shape = getTarget().getShape();
@ -357,8 +357,8 @@ public class LWWindowPeer
} }
@Override @Override
public void setAlwaysOnTop(boolean value) { public void updateAlwaysOnTopState() {
platformWindow.setAlwaysOnTop(value); platformWindow.setAlwaysOnTop(getTarget().isAlwaysOnTop());
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, 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
@ -180,7 +180,7 @@ class CFileDialog implements FileDialogPeer {
} }
@Override @Override
public void setAlwaysOnTop(boolean alwaysOnTop) { public void updateAlwaysOnTopState() {
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, 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
@ -87,7 +87,7 @@ public class CPrinterDialogPeer extends LWWindowPeer {
} }
// 1.6 peer method // 1.6 peer method
public void setAlwaysOnTop(boolean value) { public void updateAlwaysOnTopState() {
// no-op, since we just show the native print dialog // no-op, since we just show the native print dialog
} }

View File

@ -243,12 +243,17 @@ public class JPEGImageReader extends ImageReader {
* sending warnings to listeners. * sending warnings to listeners.
*/ */
protected void warningOccurred(int code) { protected void warningOccurred(int code) {
cbLock.lock();
try {
if ((code < 0) || (code > MAX_WARNING)){ if ((code < 0) || (code > MAX_WARNING)){
throw new InternalError("Invalid warning index"); throw new InternalError("Invalid warning index");
} }
processWarningOccurred processWarningOccurred
("com.sun.imageio.plugins.jpeg.JPEGImageReaderResources", ("com.sun.imageio.plugins.jpeg.JPEGImageReaderResources",
Integer.toString(code)); Integer.toString(code));
} finally {
cbLock.unlock();
}
} }
/** /**
@ -265,7 +270,12 @@ public class JPEGImageReader extends ImageReader {
* library warnings from being printed to stderr. * library warnings from being printed to stderr.
*/ */
protected void warningWithMessage(String msg) { protected void warningWithMessage(String msg) {
cbLock.lock();
try {
processWarningOccurred(msg); processWarningOccurred(msg);
} finally {
cbLock.unlock();
}
} }
public void setInput(Object input, public void setInput(Object input,
@ -274,18 +284,55 @@ public class JPEGImageReader extends ImageReader {
{ {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
super.setInput(input, seekForwardOnly, ignoreMetadata); super.setInput(input, seekForwardOnly, ignoreMetadata);
this.ignoreMetadata = ignoreMetadata; this.ignoreMetadata = ignoreMetadata;
resetInternalState(); resetInternalState();
iis = (ImageInputStream) input; // Always works iis = (ImageInputStream) input; // Always works
setSource(structPointer, iis); setSource(structPointer);
} finally { } finally {
clearThreadLock(); clearThreadLock();
} }
} }
private native void setSource(long structPointer, /**
ImageInputStream source); * This method is called from native code in order to fill
* native input buffer.
*
* We block any attempt to change the reading state during this
* method, in order to prevent a corruption of the native decoder
* state.
*
* @return number of bytes read from the stream.
*/
private int readInputData(byte[] buf, int off, int len) throws IOException {
cbLock.lock();
try {
return iis.read(buf, off, len);
} finally {
cbLock.unlock();
}
}
/**
* This method is called from the native code in order to
* skip requested number of bytes in the input stream.
*
* @param n
* @return
* @throws IOException
*/
private long skipInputBytes(long n) throws IOException {
cbLock.lock();
try {
return iis.skipBytes(n);
} finally {
cbLock.unlock();
}
}
private native void setSource(long structPointer);
private void checkTablesOnly() throws IOException { private void checkTablesOnly() throws IOException {
if (debug) { if (debug) {
@ -337,6 +384,8 @@ public class JPEGImageReader extends ImageReader {
public int getNumImages(boolean allowSearch) throws IOException { public int getNumImages(boolean allowSearch) throws IOException {
setThreadLock(); setThreadLock();
try { // locked thread try { // locked thread
cbLock.check();
return getNumImagesOnThread(allowSearch); return getNumImagesOnThread(allowSearch);
} finally { } finally {
clearThreadLock(); clearThreadLock();
@ -536,8 +585,13 @@ public class JPEGImageReader extends ImageReader {
if (debug) { if (debug) {
System.out.println("pushing back " + num + " bytes"); System.out.println("pushing back " + num + " bytes");
} }
cbLock.lock();
try {
iis.seek(iis.getStreamPosition()-num); iis.seek(iis.getStreamPosition()-num);
// The buffer is clear after this, so no need to set haveSeeked. // The buffer is clear after this, so no need to set haveSeeked.
} finally {
cbLock.unlock();
}
} }
/** /**
@ -644,7 +698,12 @@ public class JPEGImageReader extends ImageReader {
* Ignore this profile. * Ignore this profile.
*/ */
iccCS = null; iccCS = null;
cbLock.lock();
try {
warningOccurred(WARNING_IGNORE_INVALID_ICC); warningOccurred(WARNING_IGNORE_INVALID_ICC);
} finally {
cbLock.unlock();
}
} }
} }
} }
@ -653,6 +712,7 @@ public class JPEGImageReader extends ImageReader {
setThreadLock(); setThreadLock();
try { try {
if (currentImage != imageIndex) { if (currentImage != imageIndex) {
cbLock.check();
readHeader(imageIndex, true); readHeader(imageIndex, true);
} }
return width; return width;
@ -665,6 +725,7 @@ public class JPEGImageReader extends ImageReader {
setThreadLock(); setThreadLock();
try { try {
if (currentImage != imageIndex) { if (currentImage != imageIndex) {
cbLock.check();
readHeader(imageIndex, true); readHeader(imageIndex, true);
} }
return height; return height;
@ -693,6 +754,8 @@ public class JPEGImageReader extends ImageReader {
setThreadLock(); setThreadLock();
try { try {
if (currentImage != imageIndex) { if (currentImage != imageIndex) {
cbLock.check();
readHeader(imageIndex, true); readHeader(imageIndex, true);
} }
@ -716,6 +779,7 @@ public class JPEGImageReader extends ImageReader {
private Iterator getImageTypesOnThread(int imageIndex) private Iterator getImageTypesOnThread(int imageIndex)
throws IOException { throws IOException {
if (currentImage != imageIndex) { if (currentImage != imageIndex) {
cbLock.check();
readHeader(imageIndex, true); readHeader(imageIndex, true);
} }
@ -931,6 +995,7 @@ public class JPEGImageReader extends ImageReader {
setThreadLock(); setThreadLock();
try { try {
if (!tablesOnlyChecked) { if (!tablesOnlyChecked) {
cbLock.check();
checkTablesOnly(); checkTablesOnly();
} }
return streamMetadata; return streamMetadata;
@ -951,6 +1016,8 @@ public class JPEGImageReader extends ImageReader {
return imageMetadata; return imageMetadata;
} }
cbLock.check();
gotoImage(imageIndex); gotoImage(imageIndex);
imageMetadata = new JPEGMetadata(false, false, iis, this); imageMetadata = new JPEGMetadata(false, false, iis, this);
@ -967,6 +1034,7 @@ public class JPEGImageReader extends ImageReader {
throws IOException { throws IOException {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
try { try {
readInternal(imageIndex, param, false); readInternal(imageIndex, param, false);
} catch (RuntimeException e) { } catch (RuntimeException e) {
@ -1196,6 +1264,8 @@ public class JPEGImageReader extends ImageReader {
} }
target.setRect(destROI.x, destROI.y + y, raster); target.setRect(destROI.x, destROI.y + y, raster);
cbLock.lock();
try {
processImageUpdate(image, processImageUpdate(image,
destROI.x, destROI.y+y, destROI.x, destROI.y+y,
raster.getWidth(), 1, raster.getWidth(), 1,
@ -1249,6 +1319,9 @@ public class JPEGImageReader extends ImageReader {
processImageProgress(percentOfPass * 100.0F); processImageProgress(percentOfPass * 100.0F);
} }
} }
} finally {
cbLock.unlock();
}
} }
private void initProgressData() { private void initProgressData() {
@ -1260,6 +1333,8 @@ public class JPEGImageReader extends ImageReader {
} }
private void passStarted (int pass) { private void passStarted (int pass) {
cbLock.lock();
try {
this.pass = pass; this.pass = pass;
previousPassPercentage = percentToDate; previousPassPercentage = percentToDate;
processPassStarted(image, processPassStarted(image,
@ -1269,24 +1344,47 @@ public class JPEGImageReader extends ImageReader {
0, 0, 0, 0,
1,1, 1,1,
destinationBands); destinationBands);
} finally {
cbLock.unlock();
}
} }
private void passComplete () { private void passComplete () {
cbLock.lock();
try {
processPassComplete(image); processPassComplete(image);
} finally {
cbLock.unlock();
}
} }
void thumbnailStarted(int thumbnailIndex) { void thumbnailStarted(int thumbnailIndex) {
cbLock.lock();
try {
processThumbnailStarted(currentImage, thumbnailIndex); processThumbnailStarted(currentImage, thumbnailIndex);
} finally {
cbLock.unlock();
}
} }
// Provide access to protected superclass method // Provide access to protected superclass method
void thumbnailProgress(float percentageDone) { void thumbnailProgress(float percentageDone) {
cbLock.lock();
try {
processThumbnailProgress(percentageDone); processThumbnailProgress(percentageDone);
} finally {
cbLock.unlock();
}
} }
// Provide access to protected superclass method // Provide access to protected superclass method
void thumbnailComplete() { void thumbnailComplete() {
cbLock.lock();
try {
processThumbnailComplete(); processThumbnailComplete();
} finally {
cbLock.unlock();
}
} }
/** /**
@ -1310,6 +1408,11 @@ public class JPEGImageReader extends ImageReader {
public void abort() { public void abort() {
setThreadLock(); setThreadLock();
try { try {
/**
* NB: we do not check the call back lock here,
* we allow to abort the reader any time.
*/
super.abort(); super.abort();
abortRead(structPointer); abortRead(structPointer);
} finally { } finally {
@ -1332,6 +1435,7 @@ public class JPEGImageReader extends ImageReader {
setThreadLock(); setThreadLock();
Raster retval = null; Raster retval = null;
try { try {
cbLock.check();
/* /*
* This could be further optimized by not resetting the dest. * This could be further optimized by not resetting the dest.
* offset and creating a translated raster in readInternal() * offset and creating a translated raster in readInternal()
@ -1371,6 +1475,8 @@ public class JPEGImageReader extends ImageReader {
public int getNumThumbnails(int imageIndex) throws IOException { public int getNumThumbnails(int imageIndex) throws IOException {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
getImageMetadata(imageIndex); // checks iis state for us getImageMetadata(imageIndex); // checks iis state for us
// Now check the jfif segments // Now check the jfif segments
JFIFMarkerSegment jfif = JFIFMarkerSegment jfif =
@ -1391,6 +1497,8 @@ public class JPEGImageReader extends ImageReader {
throws IOException { throws IOException {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
if ((thumbnailIndex < 0) if ((thumbnailIndex < 0)
|| (thumbnailIndex >= getNumThumbnails(imageIndex))) { || (thumbnailIndex >= getNumThumbnails(imageIndex))) {
throw new IndexOutOfBoundsException("No such thumbnail"); throw new IndexOutOfBoundsException("No such thumbnail");
@ -1409,6 +1517,8 @@ public class JPEGImageReader extends ImageReader {
throws IOException { throws IOException {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
if ((thumbnailIndex < 0) if ((thumbnailIndex < 0)
|| (thumbnailIndex >= getNumThumbnails(imageIndex))) { || (thumbnailIndex >= getNumThumbnails(imageIndex))) {
throw new IndexOutOfBoundsException("No such thumbnail"); throw new IndexOutOfBoundsException("No such thumbnail");
@ -1428,6 +1538,8 @@ public class JPEGImageReader extends ImageReader {
throws IOException { throws IOException {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
if ((thumbnailIndex < 0) if ((thumbnailIndex < 0)
|| (thumbnailIndex >= getNumThumbnails(imageIndex))) { || (thumbnailIndex >= getNumThumbnails(imageIndex))) {
throw new IndexOutOfBoundsException("No such thumbnail"); throw new IndexOutOfBoundsException("No such thumbnail");
@ -1468,6 +1580,7 @@ public class JPEGImageReader extends ImageReader {
public void reset() { public void reset() {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
super.reset(); super.reset();
} finally { } finally {
clearThreadLock(); clearThreadLock();
@ -1479,6 +1592,8 @@ public class JPEGImageReader extends ImageReader {
public void dispose() { public void dispose() {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
if (structPointer != 0) { if (structPointer != 0) {
disposerRecord.dispose(); disposerRecord.dispose();
structPointer = 0; structPointer = 0;
@ -1540,6 +1655,36 @@ public class JPEGImageReader extends ImageReader {
theThread = null; theThread = null;
} }
} }
private CallBackLock cbLock = new CallBackLock();
private static class CallBackLock {
private State lockState;
CallBackLock() {
lockState = State.Unlocked;
}
void check() {
if (lockState != State.Unlocked) {
throw new IllegalStateException("Access to the reader is not allowed");
}
}
private void lock() {
lockState = State.Locked;
}
private void unlock() {
lockState = State.Unlocked;
}
private static enum State {
Unlocked,
Locked
}
}
} }
/** /**

View File

@ -183,8 +183,7 @@ public class JPEGImageWriter extends ImageWriter {
return null; return null;
} }
}); });
initWriterIDs(ImageOutputStream.class, initWriterIDs(JPEGQTable.class,
JPEGQTable.class,
JPEGHuffmanTable.class); JPEGHuffmanTable.class);
} }
@ -200,11 +199,13 @@ public class JPEGImageWriter extends ImageWriter {
public void setOutput(Object output) { public void setOutput(Object output) {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
super.setOutput(output); // validates output super.setOutput(output); // validates output
resetInternalState(); resetInternalState();
ios = (ImageOutputStream) output; // so this will always work ios = (ImageOutputStream) output; // so this will always work
// Set the native destination // Set the native destination
setDest(structPointer, ios); setDest(structPointer);
} finally { } finally {
clearThreadLock(); clearThreadLock();
} }
@ -359,6 +360,8 @@ public class JPEGImageWriter extends ImageWriter {
ImageWriteParam param) throws IOException { ImageWriteParam param) throws IOException {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
writeOnThread(streamMetadata, image, param); writeOnThread(streamMetadata, image, param);
} finally { } finally {
clearThreadLock(); clearThreadLock();
@ -1082,6 +1085,8 @@ public class JPEGImageWriter extends ImageWriter {
haveMetadata, haveMetadata,
restartInterval); restartInterval);
cbLock.lock();
try {
if (aborted) { if (aborted) {
processWriteAborted(); processWriteAborted();
} else { } else {
@ -1089,6 +1094,9 @@ public class JPEGImageWriter extends ImageWriter {
} }
ios.flush(); ios.flush();
} finally {
cbLock.unlock();
}
currentImage++; // After a successful write currentImage++; // After a successful write
} }
@ -1096,6 +1104,8 @@ public class JPEGImageWriter extends ImageWriter {
throws IOException { throws IOException {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
prepareWriteSequenceOnThread(streamMetadata); prepareWriteSequenceOnThread(streamMetadata);
} finally { } finally {
clearThreadLock(); clearThreadLock();
@ -1175,6 +1185,8 @@ public class JPEGImageWriter extends ImageWriter {
throws IOException { throws IOException {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
if (sequencePrepared == false) { if (sequencePrepared == false) {
throw new IllegalStateException("sequencePrepared not called!"); throw new IllegalStateException("sequencePrepared not called!");
} }
@ -1188,6 +1200,8 @@ public class JPEGImageWriter extends ImageWriter {
public void endWriteSequence() throws IOException { public void endWriteSequence() throws IOException {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
if (sequencePrepared == false) { if (sequencePrepared == false) {
throw new IllegalStateException("sequencePrepared not called!"); throw new IllegalStateException("sequencePrepared not called!");
} }
@ -1200,6 +1214,10 @@ public class JPEGImageWriter extends ImageWriter {
public synchronized void abort() { public synchronized void abort() {
setThreadLock(); setThreadLock();
try { try {
/**
* NB: we do not check the call back lock here, we allow to abort
* the reader any time.
*/
super.abort(); super.abort();
abortWrite(structPointer); abortWrite(structPointer);
} finally { } finally {
@ -1223,6 +1241,8 @@ public class JPEGImageWriter extends ImageWriter {
public void reset() { public void reset() {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
super.reset(); super.reset();
} finally { } finally {
clearThreadLock(); clearThreadLock();
@ -1232,6 +1252,8 @@ public class JPEGImageWriter extends ImageWriter {
public void dispose() { public void dispose() {
setThreadLock(); setThreadLock();
try { try {
cbLock.check();
if (structPointer != 0) { if (structPointer != 0) {
disposerRecord.dispose(); disposerRecord.dispose();
structPointer = 0; structPointer = 0;
@ -1251,6 +1273,8 @@ public class JPEGImageWriter extends ImageWriter {
* sending warnings to listeners. * sending warnings to listeners.
*/ */
void warningOccurred(int code) { void warningOccurred(int code) {
cbLock.lock();
try {
if ((code < 0) || (code > MAX_WARNING)){ if ((code < 0) || (code > MAX_WARNING)){
throw new InternalError("Invalid warning index"); throw new InternalError("Invalid warning index");
} }
@ -1258,6 +1282,9 @@ public class JPEGImageWriter extends ImageWriter {
(currentImage, (currentImage,
"com.sun.imageio.plugins.jpeg.JPEGImageWriterResources", "com.sun.imageio.plugins.jpeg.JPEGImageWriterResources",
Integer.toString(code)); Integer.toString(code));
} finally {
cbLock.unlock();
}
} }
/** /**
@ -1274,21 +1301,41 @@ public class JPEGImageWriter extends ImageWriter {
* library warnings from being printed to stderr. * library warnings from being printed to stderr.
*/ */
void warningWithMessage(String msg) { void warningWithMessage(String msg) {
cbLock.lock();
try {
processWarningOccurred(currentImage, msg); processWarningOccurred(currentImage, msg);
} finally {
cbLock.unlock();
}
} }
void thumbnailStarted(int thumbnailIndex) { void thumbnailStarted(int thumbnailIndex) {
cbLock.lock();
try {
processThumbnailStarted(currentImage, thumbnailIndex); processThumbnailStarted(currentImage, thumbnailIndex);
} finally {
cbLock.unlock();
}
} }
// Provide access to protected superclass method // Provide access to protected superclass method
void thumbnailProgress(float percentageDone) { void thumbnailProgress(float percentageDone) {
cbLock.lock();
try {
processThumbnailProgress(percentageDone); processThumbnailProgress(percentageDone);
} finally {
cbLock.unlock();
}
} }
// Provide access to protected superclass method // Provide access to protected superclass method
void thumbnailComplete() { void thumbnailComplete() {
cbLock.lock();
try {
processThumbnailComplete(); processThumbnailComplete();
} finally {
cbLock.unlock();
}
} }
///////// End of Package-access API ///////// End of Package-access API
@ -1615,16 +1662,14 @@ public class JPEGImageWriter extends ImageWriter {
////////////// Native methods and callbacks ////////////// Native methods and callbacks
/** Sets up static native structures. */ /** Sets up static native structures. */
private static native void initWriterIDs(Class iosClass, private static native void initWriterIDs(Class qTableClass,
Class qTableClass,
Class huffClass); Class huffClass);
/** Sets up per-writer native structure and returns a pointer to it. */ /** Sets up per-writer native structure and returns a pointer to it. */
private native long initJPEGImageWriter(); private native long initJPEGImageWriter();
/** Sets up native structures for output stream */ /** Sets up native structures for output stream */
private native void setDest(long structPointer, private native void setDest(long structPointer);
ImageOutputStream ios);
/** /**
* Returns <code>true</code> if the write was aborted. * Returns <code>true</code> if the write was aborted.
@ -1749,7 +1794,12 @@ public class JPEGImageWriter extends ImageWriter {
} }
raster.setRect(sourceLine); raster.setRect(sourceLine);
if ((y > 7) && (y%8 == 0)) { // Every 8 scanlines if ((y > 7) && (y%8 == 0)) { // Every 8 scanlines
cbLock.lock();
try {
processImageProgress((float) y / (float) sourceHeight * 100.0F); processImageProgress((float) y / (float) sourceHeight * 100.0F);
} finally {
cbLock.unlock();
}
} }
} }
@ -1777,6 +1827,25 @@ public class JPEGImageWriter extends ImageWriter {
} }
} }
/**
* This method is called from native code in order to write encoder
* output to the destination.
*
* We block any attempt to change the writer state during this
* method, in order to prevent a corruption of the native encoder
* state.
*/
private void writeOutputData(byte[] data, int offset, int len)
throws IOException
{
cbLock.lock();
try {
ios.write(data, offset, len);
} finally {
cbLock.unlock();
}
}
private Thread theThread = null; private Thread theThread = null;
private int theLockCount = 0; private int theLockCount = 0;
@ -1811,4 +1880,34 @@ public class JPEGImageWriter extends ImageWriter {
theThread = null; theThread = null;
} }
} }
private CallBackLock cbLock = new CallBackLock();
private static class CallBackLock {
private State lockState;
CallBackLock() {
lockState = State.Unlocked;
}
void check() {
if (lockState != State.Unlocked) {
throw new IllegalStateException("Access to the writer is not allowed");
}
}
private void lock() {
lockState = State.Locked;
}
private void unlock() {
lockState = State.Unlocked;
}
private static enum State {
Unlocked,
Locked
}
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2013, 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
@ -32,6 +32,7 @@ import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.security.Permission; import java.security.Permission;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
@ -213,7 +214,6 @@ public class MBeanInstantiator {
Object moi; Object moi;
// ------------------------------ // ------------------------------
// ------------------------------ // ------------------------------
Constructor<?> cons = findConstructor(theClass, null); Constructor<?> cons = findConstructor(theClass, null);
@ -224,6 +224,7 @@ public class MBeanInstantiator {
// Instantiate the new object // Instantiate the new object
try { try {
ReflectUtil.checkPackageAccess(theClass); ReflectUtil.checkPackageAccess(theClass);
ensureClassAccess(theClass);
moi= cons.newInstance(); moi= cons.newInstance();
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
// Wrap the exception. // Wrap the exception.
@ -270,7 +271,6 @@ public class MBeanInstantiator {
checkMBeanPermission(theClass, null, null, "instantiate"); checkMBeanPermission(theClass, null, null, "instantiate");
// Instantiate the new object // Instantiate the new object
// ------------------------------ // ------------------------------
// ------------------------------ // ------------------------------
final Class<?>[] tab; final Class<?>[] tab;
@ -300,6 +300,7 @@ public class MBeanInstantiator {
} }
try { try {
ReflectUtil.checkPackageAccess(theClass); ReflectUtil.checkPackageAccess(theClass);
ensureClassAccess(theClass);
moi = cons.newInstance(params); moi = cons.newInstance(params);
} }
catch (NoSuchMethodError error) { catch (NoSuchMethodError error) {
@ -741,4 +742,13 @@ public class MBeanInstantiator {
sm.checkPermission(perm); sm.checkPermission(perm);
} }
} }
private static void ensureClassAccess(Class clazz)
throws IllegalAccessException
{
int mod = clazz.getModifiers();
if (!Modifier.isPublic(mod)) {
throw new IllegalAccessException("Class is not public and can't be instantiated");
}
}
} }

View File

@ -56,7 +56,7 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
// from simultaneous creation and destruction // from simultaneous creation and destruction
// reduces possibility of deadlock, compared to // reduces possibility of deadlock, compared to
// synchronizing to the class instance // synchronizing to the class instance
private Object traRecLock = new Object(); private final Object traRecLock = new Object();
// DEVICE ATTRIBUTES // DEVICE ATTRIBUTES
@ -474,7 +474,7 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
This is necessary for Receivers retrieved via MidiSystem.getReceiver() This is necessary for Receivers retrieved via MidiSystem.getReceiver()
(which opens the device implicitely). (which opens the device implicitely).
*/ */
protected abstract class AbstractReceiver implements MidiDeviceReceiver { abstract class AbstractReceiver implements MidiDeviceReceiver {
private boolean open = true; private boolean open = true;
@ -483,24 +483,24 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
Receiver. Therefore, subclasses should not override this method. Receiver. Therefore, subclasses should not override this method.
Instead, they should implement implSend(). Instead, they should implement implSend().
*/ */
public synchronized void send(MidiMessage message, long timeStamp) { @Override
if (open) { public final synchronized void send(final MidiMessage message,
implSend(message, timeStamp); final long timeStamp) {
} else { if (!open) {
throw new IllegalStateException("Receiver is not open"); throw new IllegalStateException("Receiver is not open");
} }
implSend(message, timeStamp);
} }
abstract void implSend(MidiMessage message, long timeStamp);
protected abstract void implSend(MidiMessage message, long timeStamp);
/** Close the Receiver. /** Close the Receiver.
* Here, the call to the magic method closeInternal() takes place. * Here, the call to the magic method closeInternal() takes place.
* Therefore, subclasses that override this method must call * Therefore, subclasses that override this method must call
* 'super.close()'. * 'super.close()'.
*/ */
public void close() { @Override
public final void close() {
open = false; open = false;
synchronized (AbstractMidiDevice.this.traRecLock) { synchronized (AbstractMidiDevice.this.traRecLock) {
AbstractMidiDevice.this.getReceiverList().remove(this); AbstractMidiDevice.this.getReceiverList().remove(this);
@ -508,11 +508,12 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
AbstractMidiDevice.this.closeInternal(this); AbstractMidiDevice.this.closeInternal(this);
} }
public MidiDevice getMidiDevice() { @Override
public final MidiDevice getMidiDevice() {
return AbstractMidiDevice.this; return AbstractMidiDevice.this;
} }
protected boolean isOpen() { final boolean isOpen() {
return open; return open;
} }

View File

@ -32,7 +32,7 @@ import javax.sound.midi.*;
* *
* @author Florian Bomers * @author Florian Bomers
*/ */
class FastShortMessage extends ShortMessage { final class FastShortMessage extends ShortMessage {
private int packedMsg; private int packedMsg;
public FastShortMessage(int packedMsg) throws InvalidMidiDataException { public FastShortMessage(int packedMsg) throws InvalidMidiDataException {

View File

@ -32,7 +32,7 @@ import javax.sound.midi.*;
* *
* @author Florian Bomers * @author Florian Bomers
*/ */
class FastSysexMessage extends SysexMessage { final class FastSysexMessage extends SysexMessage {
FastSysexMessage(byte[] data) throws InvalidMidiDataException { FastSysexMessage(byte[] data) throws InvalidMidiDataException {
super(data); super(data);

View File

@ -103,9 +103,9 @@ class MidiOutDevice extends AbstractMidiDevice {
class MidiOutReceiver extends AbstractReceiver { class MidiOutReceiver extends AbstractReceiver {
protected void implSend(MidiMessage message, long timeStamp) { void implSend(final MidiMessage message, final long timeStamp) {
int length = message.getLength(); final int length = message.getLength();
int status = message.getStatus(); final int status = message.getStatus();
if (length <= 3 && status != 0xF0 && status != 0xF7) { if (length <= 3 && status != 0xF0 && status != 0xF7) {
int packedMsg; int packedMsg;
if (message instanceof ShortMessage) { if (message instanceof ShortMessage) {
@ -140,11 +140,15 @@ class MidiOutDevice extends AbstractMidiDevice {
} }
nSendShortMessage(id, packedMsg, timeStamp); nSendShortMessage(id, packedMsg, timeStamp);
} else { } else {
final byte[] data;
if (message instanceof FastSysexMessage) { if (message instanceof FastSysexMessage) {
nSendLongMessage(id, ((FastSysexMessage) message).getReadOnlyMessage(), data = ((FastSysexMessage) message).getReadOnlyMessage();
length, timeStamp);
} else { } else {
nSendLongMessage(id, message.getMessage(), length, timeStamp); data = message.getMessage();
}
final int dataLength = Math.min(length, data.length);
if (dataLength > 0) {
nSendLongMessage(id, data, dataLength, timeStamp);
} }
} }
} }

View File

@ -1026,7 +1026,7 @@ class RealTimeSequencer extends AbstractMidiDevice implements Sequencer, AutoCon
class SequencerReceiver extends AbstractReceiver { class SequencerReceiver extends AbstractReceiver {
protected void implSend(MidiMessage message, long timeStamp) { void implSend(MidiMessage message, long timeStamp) {
if (recording) { if (recording) {
long tickPos = 0; long tickPos = 0;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2013, 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
@ -2234,7 +2234,7 @@ public class Window extends Container implements Accessible {
WindowPeer peer = (WindowPeer)this.peer; WindowPeer peer = (WindowPeer)this.peer;
synchronized(getTreeLock()) { synchronized(getTreeLock()) {
if (peer != null) { if (peer != null) {
peer.setAlwaysOnTop(alwaysOnTop); peer.updateAlwaysOnTopState();
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2013, 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
@ -53,15 +53,14 @@ public interface WindowPeer extends ContainerPeer {
void toBack(); void toBack();
/** /**
* Sets if the window should always stay on top of all other windows or * Updates the window's always-on-top state.
* not. * Sets if the window should always stay
* * on top of all other windows or not.
* @param alwaysOnTop if the window should always stay on top of all other
* windows or not
* *
* @see Window#getAlwaysOnTop()
* @see Window#setAlwaysOnTop(boolean) * @see Window#setAlwaysOnTop(boolean)
*/ */
void setAlwaysOnTop(boolean alwaysOnTop); void updateAlwaysOnTopState();
/** /**
* Updates the window's focusable state. * Updates the window's focusable state.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, 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
@ -29,7 +29,6 @@ import com.sun.beans.finder.BeanInfoFinder;
import com.sun.beans.finder.PropertyEditorFinder; import com.sun.beans.finder.PropertyEditorFinder;
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
@ -42,7 +41,7 @@ import java.util.WeakHashMap;
*/ */
final class ThreadGroupContext { final class ThreadGroupContext {
private static final Map<ThreadGroup, ThreadGroupContext> contexts = new WeakHashMap<>(); private static final WeakIdentityMap<ThreadGroupContext> contexts = new WeakIdentityMap<>();
/** /**
* Returns the appropriate {@code AppContext} for the caller, * Returns the appropriate {@code AppContext} for the caller,
@ -69,6 +68,8 @@ final class ThreadGroupContext {
private BeanInfoFinder beanInfoFinder; private BeanInfoFinder beanInfoFinder;
private PropertyEditorFinder propertyEditorFinder; private PropertyEditorFinder propertyEditorFinder;
private ThreadGroupContext() {
}
boolean isDesignTime() { boolean isDesignTime() {
return this.isDesignTime; return this.isDesignTime;

View File

@ -0,0 +1,181 @@
/*
* Copyright (c) 2013, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.beans;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
/**
* Hash table based mapping, which uses weak references to store keys
* and reference-equality in place of object-equality to compare them.
* An entry will automatically be removed when its key is no longer
* in ordinary use. Both null values and the null key are supported.
*
* @see java.util.IdentityHashMap
* @see java.util.WeakHashMap
*/
final class WeakIdentityMap<T> {
private static final int MAXIMUM_CAPACITY = 1 << 30; // it MUST be a power of two
private static final Object NULL = new Object(); // special object for null key
private final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
private Entry<T>[] table = newTable(1<<3); // table's length MUST be a power of two
private int threshold = 6; // the next size value at which to resize
private int size = 0; // the number of key-value mappings
public T get(Object key) {
removeStaleEntries();
if (key == null) {
key = NULL;
}
int hash = key.hashCode();
int index = getIndex(this.table, hash);
for (Entry<T> entry = this.table[index]; entry != null; entry = entry.next) {
if (entry.isMatched(key, hash)) {
return entry.value;
}
}
return null;
}
public T put(Object key, T value) {
removeStaleEntries();
if (key == null) {
key = NULL;
}
int hash = key.hashCode();
int index = getIndex(this.table, hash);
for (Entry<T> entry = this.table[index]; entry != null; entry = entry.next) {
if (entry.isMatched(key, hash)) {
T oldValue = entry.value;
entry.value = value;
return oldValue;
}
}
this.table[index] = new Entry<T>(key, hash, value, this.queue, this.table[index]);
if (++this.size >= this.threshold) {
if (this.table.length == MAXIMUM_CAPACITY) {
this.threshold = Integer.MAX_VALUE;
}
else {
removeStaleEntries();
Entry<T>[] table = newTable(this.table.length * 2);
transfer(this.table, table);
// If ignoring null elements and processing ref queue caused massive
// shrinkage, then restore old table. This should be rare, but avoids
// unbounded expansion of garbage-filled tables.
if (this.size >= this.threshold / 2) {
this.table = table;
this.threshold *= 2;
}
else {
transfer(table, this.table);
}
}
}
return null;
}
private void removeStaleEntries() {
for (Object ref = this.queue.poll(); ref != null; ref = this.queue.poll()) {
@SuppressWarnings("unchecked")
Entry<T> entry = (Entry<T>) ref;
int index = getIndex(this.table, entry.hash);
Entry<T> prev = this.table[index];
Entry<T> current = prev;
while (current != null) {
Entry<T> next = current.next;
if (current == entry) {
if (prev == entry) {
this.table[index] = next;
}
else {
prev.next = next;
}
entry.value = null; // Help GC
entry.next = null; // Help GC
this.size--;
break;
}
prev = current;
current = next;
}
}
}
private void transfer(Entry<T>[] oldTable, Entry<T>[] newTable) {
for (int i = 0; i < oldTable.length; i++) {
Entry<T> entry = oldTable[i];
oldTable[i] = null;
while (entry != null) {
Entry<T> next = entry.next;
Object key = entry.get();
if (key == null) {
entry.value = null; // Help GC
entry.next = null; // Help GC
this.size--;
}
else {
int index = getIndex(newTable, entry.hash);
entry.next = newTable[index];
newTable[index] = entry;
}
entry = next;
}
}
}
@SuppressWarnings("unchecked")
private Entry<T>[] newTable(int length) {
return (Entry<T>[]) new Entry<?>[length];
}
private static int getIndex(Entry<?>[] table, int hash) {
return hash & (table.length - 1);
}
private static class Entry<T> extends WeakReference<Object> {
private final int hash;
private T value;
private Entry<T> next;
Entry(Object key, int hash, T value, ReferenceQueue<Object> queue, Entry<T> next) {
super(key, queue);
this.hash = hash;
this.value = value;
this.next = next;
}
boolean isMatched(Object key, int hash) {
return (this.hash == hash) && (key == get());
}
}
}

View File

@ -41,6 +41,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import static java.io.ObjectStreamClass.processQueue; import static java.io.ObjectStreamClass.processQueue;
import sun.reflect.misc.ReflectUtil;
/** /**
* An ObjectInputStream deserializes primitive data and objects previously * An ObjectInputStream deserializes primitive data and objects previously
@ -1519,6 +1520,12 @@ public class ObjectInputStream
} }
} }
private boolean isCustomSubclass() {
// Return true if this class is a custom subclass of ObjectInputStream
return getClass().getClassLoader()
!= ObjectInputStream.class.getClassLoader();
}
/** /**
* Reads in and returns class descriptor for a dynamic proxy class. Sets * Reads in and returns class descriptor for a dynamic proxy class. Sets
* passHandle to proxy class descriptor's assigned handle. If proxy class * passHandle to proxy class descriptor's assigned handle. If proxy class
@ -1548,6 +1555,15 @@ public class ObjectInputStream
try { try {
if ((cl = resolveProxyClass(ifaces)) == null) { if ((cl = resolveProxyClass(ifaces)) == null) {
resolveEx = new ClassNotFoundException("null class"); resolveEx = new ClassNotFoundException("null class");
} else if (!Proxy.isProxyClass(cl)) {
throw new InvalidClassException("Not a proxy");
} else {
// ReflectUtil.checkProxyPackageAccess makes a test
// equivalent to isCustomSubclass so there's no need
// to condition this call to isCustomSubclass == true here.
ReflectUtil.checkProxyPackageAccess(
getClass().getClassLoader(),
cl.getInterfaces());
} }
} catch (ClassNotFoundException ex) { } catch (ClassNotFoundException ex) {
resolveEx = ex; resolveEx = ex;
@ -1589,9 +1605,12 @@ public class ObjectInputStream
Class<?> cl = null; Class<?> cl = null;
ClassNotFoundException resolveEx = null; ClassNotFoundException resolveEx = null;
bin.setBlockDataMode(true); bin.setBlockDataMode(true);
final boolean checksRequired = isCustomSubclass();
try { try {
if ((cl = resolveClass(readDesc)) == null) { if ((cl = resolveClass(readDesc)) == null) {
resolveEx = new ClassNotFoundException("null class"); resolveEx = new ClassNotFoundException("null class");
} else if (checksRequired) {
ReflectUtil.checkPackageAccess(cl);
} }
} catch (ClassNotFoundException ex) { } catch (ClassNotFoundException ex) {
resolveEx = ex; resolveEx = ex;

View File

@ -53,6 +53,7 @@ import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects; import java.util.Objects;
import sun.misc.Unsafe; import sun.misc.Unsafe;
import sun.reflect.CallerSensitive;
import sun.reflect.ConstantPool; import sun.reflect.ConstantPool;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.reflect.ReflectionFactory; import sun.reflect.ReflectionFactory;
@ -250,9 +251,11 @@ public final class Class<T> implements java.io.Serializable,
* by this method fails * by this method fails
* @exception ClassNotFoundException if the class cannot be located * @exception ClassNotFoundException if the class cannot be located
*/ */
@CallerSensitive
public static Class<?> forName(String className) public static Class<?> forName(String className)
throws ClassNotFoundException { throws ClassNotFoundException {
return forName0(className, true, ClassLoader.getCallerClassLoader()); return forName0(className, true,
ClassLoader.getClassLoader(Reflection.getCallerClass()));
} }
@ -317,6 +320,7 @@ public final class Class<T> implements java.io.Serializable,
* @see java.lang.ClassLoader * @see java.lang.ClassLoader
* @since 1.2 * @since 1.2
*/ */
@CallerSensitive
public static Class<?> forName(String name, boolean initialize, public static Class<?> forName(String name, boolean initialize,
ClassLoader loader) ClassLoader loader)
throws ClassNotFoundException throws ClassNotFoundException
@ -324,7 +328,7 @@ public final class Class<T> implements java.io.Serializable,
if (sun.misc.VM.isSystemDomainLoader(loader)) { if (sun.misc.VM.isSystemDomainLoader(loader)) {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader(); ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass());
if (!sun.misc.VM.isSystemDomainLoader(ccl)) { if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
sm.checkPermission( sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION); SecurityConstants.GET_CLASSLOADER_PERMISSION);
@ -386,18 +390,14 @@ public final class Class<T> implements java.io.Serializable,
* </ul> * </ul>
* *
*/ */
@CallerSensitive
public T newInstance() public T newInstance()
throws InstantiationException, IllegalAccessException throws InstantiationException, IllegalAccessException
{ {
if (System.getSecurityManager() != null) { if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false); checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
return newInstance0();
} }
private T newInstance0()
throws InstantiationException, IllegalAccessException
{
// NOTE: the following code may not be strictly correct under // NOTE: the following code may not be strictly correct under
// the current Java memory model. // the current Java memory model.
@ -432,7 +432,7 @@ public final class Class<T> implements java.io.Serializable,
// Security check (same as in java.lang.reflect.Constructor) // Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers(); int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) { if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class<?> caller = Reflection.getCallerClass(3); Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) { if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers); Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller; newInstanceCallerCache = caller;
@ -674,16 +674,14 @@ public final class Class<T> implements java.io.Serializable,
* @see SecurityManager#checkPermission * @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission * @see java.lang.RuntimePermission
*/ */
@CallerSensitive
public ClassLoader getClassLoader() { public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0(); ClassLoader cl = getClassLoader0();
if (cl == null) if (cl == null)
return null; return null;
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader(); ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
if (ClassLoader.needsClassLoaderPermissionCheck(ccl, cl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
} }
return cl; return cl;
} }
@ -1392,11 +1390,9 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Class<?>[] getClasses() { public Class<?>[] getClasses() {
// be very careful not to change the stack depth of this checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
// Privileged so this implementation can look at DECLARED classes, // Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here // something the caller might not have privilege to do. The code here
@ -1467,11 +1463,9 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Field[] getFields() throws SecurityException { public Field[] getFields() throws SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetPublicFields(null)); return copyFields(privateGetPublicFields(null));
} }
@ -1518,11 +1512,9 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Method[] getMethods() throws SecurityException { public Method[] getMethods() throws SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetPublicMethods()); return copyMethods(privateGetPublicMethods());
} }
@ -1567,11 +1559,9 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Constructor<?>[] getConstructors() throws SecurityException { public Constructor<?>[] getConstructors() throws SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(true)); return copyConstructors(privateGetDeclaredConstructors(true));
} }
@ -1625,12 +1615,10 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Field getField(String name) public Field getField(String name)
throws NoSuchFieldException, SecurityException { throws NoSuchFieldException, SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Field field = getField0(name); Field field = getField0(name);
if (field == null) { if (field == null) {
throw new NoSuchFieldException(name); throw new NoSuchFieldException(name);
@ -1710,12 +1698,10 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Method getMethod(String name, Class<?>... parameterTypes) public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException { throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Method method = getMethod0(name, parameterTypes); Method method = getMethod0(name, parameterTypes);
if (method == null) { if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@ -1764,12 +1750,10 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Constructor<T> getConstructor(Class<?>... parameterTypes) public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException { throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.PUBLIC); return getConstructor0(parameterTypes, Member.PUBLIC);
} }
@ -1807,11 +1791,9 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Class<?>[] getDeclaredClasses() throws SecurityException { public Class<?>[] getDeclaredClasses() throws SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
return getDeclaredClasses0(); return getDeclaredClasses0();
} }
@ -1851,11 +1833,9 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Field[] getDeclaredFields() throws SecurityException { public Field[] getDeclaredFields() throws SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetDeclaredFields(false)); return copyFields(privateGetDeclaredFields(false));
} }
@ -1899,11 +1879,9 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Method[] getDeclaredMethods() throws SecurityException { public Method[] getDeclaredMethods() throws SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetDeclaredMethods(false)); return copyMethods(privateGetDeclaredMethods(false));
} }
@ -1944,11 +1922,9 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Constructor<?>[] getDeclaredConstructors() throws SecurityException { public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(false)); return copyConstructors(privateGetDeclaredConstructors(false));
} }
@ -1987,12 +1963,10 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Field getDeclaredField(String name) public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException { throws NoSuchFieldException, SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Field field = searchFields(privateGetDeclaredFields(false), name); Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) { if (field == null) {
throw new NoSuchFieldException(name); throw new NoSuchFieldException(name);
@ -2042,12 +2016,10 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException { throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes); Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) { if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@ -2092,12 +2064,10 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since JDK1.1 * @since JDK1.1
*/ */
@CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException { throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.DECLARED); return getConstructor0(parameterTypes, Member.DECLARED);
} }
@ -2255,23 +2225,40 @@ public final class Class<T> implements java.io.Serializable,
*/ */
static native Class<?> getPrimitiveClass(String name); static native Class<?> getPrimitiveClass(String name);
private static boolean isCheckMemberAccessOverridden(SecurityManager smgr) {
if (smgr.getClass() == SecurityManager.class) return false;
Class<?>[] paramTypes = new Class<?>[] {Class.class, int.class};
return smgr.getClass().getMethod0("checkMemberAccess", paramTypes).
getDeclaringClass() != SecurityManager.class;
}
/* /*
* Check if client is allowed to access members. If access is denied, * Check if client is allowed to access members. If access is denied,
* throw a SecurityException. * throw a SecurityException.
* *
* Be very careful not to change the stack depth of this checkMemberAccess
* call for security reasons.
* See java.lang.SecurityManager.checkMemberAccess.
*
* <p> Default policy: allow all clients access with normal Java access * <p> Default policy: allow all clients access with normal Java access
* control. * control.
*/ */
private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) { private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {
SecurityManager s = System.getSecurityManager(); final SecurityManager s = System.getSecurityManager();
if (s != null) { if (s != null) {
final ClassLoader ccl = ClassLoader.getClassLoader(caller);
final ClassLoader cl = getClassLoader0();
if (!isCheckMemberAccessOverridden(s)) {
// Inlined SecurityManager.checkMemberAccess
if (which != Member.PUBLIC) {
if (ccl != cl) {
s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
}
}
} else {
// Don't refactor; otherwise break the stack depth for
// checkMemberAccess of subclasses of SecurityManager as specified.
s.checkMemberAccess(this, which); s.checkMemberAccess(this, which);
ClassLoader cl = getClassLoader0(); }
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) { if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName(); String name = this.getName();
int i = name.lastIndexOf('.'); int i = name.lastIndexOf('.');

View File

@ -55,6 +55,7 @@ import sun.misc.CompoundEnumeration;
import sun.misc.Resource; import sun.misc.Resource;
import sun.misc.URLClassPath; import sun.misc.URLClassPath;
import sun.misc.VM; import sun.misc.VM;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
@ -1159,11 +1160,6 @@ public abstract class ClassLoader {
return java.util.Collections.emptyEnumeration(); return java.util.Collections.emptyEnumeration();
} }
// index 0: java.lang.ClassLoader.class
// index 1: the immediate caller of index 0.
// index 2: the immediate caller of index 1.
private static native Class<? extends ClassLoader> getCaller(int index);
/** /**
* Registers the caller as parallel capable.</p> * Registers the caller as parallel capable.</p>
* The registration succeeds if and only if all of the following * The registration succeeds if and only if all of the following
@ -1179,8 +1175,11 @@ public abstract class ClassLoader {
* *
* @since 1.7 * @since 1.7
*/ */
@CallerSensitive
protected static boolean registerAsParallelCapable() { protected static boolean registerAsParallelCapable() {
return ParallelLoaders.register(getCaller(1)); Class<? extends ClassLoader> callerClass =
Reflection.getCallerClass().asSubclass(ClassLoader.class);
return ParallelLoaders.register(callerClass);
} }
/** /**
@ -1340,15 +1339,13 @@ public abstract class ClassLoader {
* *
* @since 1.2 * @since 1.2
*/ */
@CallerSensitive
public final ClassLoader getParent() { public final ClassLoader getParent() {
if (parent == null) if (parent == null)
return null; return null;
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
ClassLoader ccl = getCallerClassLoader(); checkClassLoaderPermission(this, Reflection.getCallerClass());
if (needsClassLoaderPermissionCheck(ccl, this)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
} }
return parent; return parent;
} }
@ -1408,6 +1405,7 @@ public abstract class ClassLoader {
* *
* @revised 1.4 * @revised 1.4
*/ */
@CallerSensitive
public static ClassLoader getSystemClassLoader() { public static ClassLoader getSystemClassLoader() {
initSystemClassLoader(); initSystemClassLoader();
if (scl == null) { if (scl == null) {
@ -1415,10 +1413,7 @@ public abstract class ClassLoader {
} }
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
ClassLoader ccl = getCallerClassLoader(); checkClassLoaderPermission(scl, Reflection.getCallerClass());
if (needsClassLoaderPermissionCheck(ccl, scl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
} }
return scl; return scl;
} }
@ -1471,7 +1466,7 @@ public abstract class ClassLoader {
// class loader 'from' is same as class loader 'to' or an ancestor // class loader 'from' is same as class loader 'to' or an ancestor
// of 'to'. The class loader in a system domain can access // of 'to'. The class loader in a system domain can access
// any class loader. // any class loader.
static boolean needsClassLoaderPermissionCheck(ClassLoader from, private static boolean needsClassLoaderPermissionCheck(ClassLoader from,
ClassLoader to) ClassLoader to)
{ {
if (from == to) if (from == to)
@ -1483,13 +1478,8 @@ public abstract class ClassLoader {
return !to.isAncestor(from); return !to.isAncestor(from);
} }
// Returns the invoker's class loader, or null if none. // Returns the class's class loader, or null if none.
// NOTE: This must always be invoked when there is exactly one intervening static ClassLoader getClassLoader(Class<?> caller) {
// frame from the core libraries on the stack between this method's
// invocation and the desired invoker.
static ClassLoader getCallerClassLoader() {
// NOTE use of more generic Reflection.getCallerClass()
Class<?> caller = Reflection.getCallerClass(3);
// This can be null if the VM is requesting it // This can be null if the VM is requesting it
if (caller == null) { if (caller == null) {
return null; return null;
@ -1498,6 +1488,17 @@ public abstract class ClassLoader {
return caller.getClassLoader0(); return caller.getClassLoader0();
} }
static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// caller can be null if the VM is requesting it
ClassLoader ccl = getClassLoader(caller);
if (needsClassLoaderPermissionCheck(ccl, cl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
}
// The class loader for the system // The class loader for the system
// @GuardedBy("ClassLoader.class") // @GuardedBy("ClassLoader.class")
private static ClassLoader scl; private static ClassLoader scl;

View File

@ -49,6 +49,8 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import sun.net.www.ParseUtil; import sun.net.www.ParseUtil;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
@ -273,8 +275,9 @@ public class Package implements java.lang.reflect.AnnotatedElement {
* @return the package of the requested name. It may be null if no package * @return the package of the requested name. It may be null if no package
* information is available from the archive or codebase. * information is available from the archive or codebase.
*/ */
@CallerSensitive
public static Package getPackage(String name) { public static Package getPackage(String name) {
ClassLoader l = ClassLoader.getCallerClassLoader(); ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
if (l != null) { if (l != null) {
return l.getPackage(name); return l.getPackage(name);
} else { } else {
@ -294,8 +297,9 @@ public class Package implements java.lang.reflect.AnnotatedElement {
* @return a new array of packages known to the callers {@code ClassLoader} * @return a new array of packages known to the callers {@code ClassLoader}
* instance. An zero length array is returned if none are known. * instance. An zero length array is returned if none are known.
*/ */
@CallerSensitive
public static Package[] getPackages() { public static Package[] getPackages() {
ClassLoader l = ClassLoader.getCallerClassLoader(); ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
if (l != null) { if (l != null) {
return l.getPackages(); return l.getPackages();
} else { } else {

View File

@ -30,6 +30,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.security.AccessControlException;
import java.util.Arrays; import java.util.Arrays;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -1024,13 +1025,24 @@ public final class ProcessBuilder
redirects, redirects,
redirectErrorStream); redirectErrorStream);
} catch (IOException e) { } catch (IOException e) {
String exceptionInfo = ": " + e.getMessage();
Throwable cause = e;
if (security != null) {
// Can not disclose the fail reason for read-protected files.
try {
security.checkRead(prog);
} catch (AccessControlException ace) {
exceptionInfo = "";
cause = ace;
}
}
// It's much easier for us to create a high-quality error // It's much easier for us to create a high-quality error
// message than the low-level C code which found the problem. // message than the low-level C code which found the problem.
throw new IOException( throw new IOException(
"Cannot run program \"" + prog + "\"" "Cannot run program \"" + prog + "\""
+ (dir == null ? "" : " (in directory \"" + dir + "\")") + (dir == null ? "" : " (in directory \"" + dir + "\")")
+ ": " + e.getMessage(), + exceptionInfo,
e); cause);
} }
} }
} }

View File

@ -27,6 +27,8 @@ package java.lang;
import java.io.*; import java.io.*;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
/** /**
* Every Java application has a single instance of class * Every Java application has a single instance of class
@ -790,8 +792,9 @@ public class Runtime {
* @see java.lang.SecurityException * @see java.lang.SecurityException
* @see java.lang.SecurityManager#checkLink(java.lang.String) * @see java.lang.SecurityManager#checkLink(java.lang.String)
*/ */
@CallerSensitive
public void load(String filename) { public void load(String filename) {
load0(System.getCallerClass(), filename); load0(Reflection.getCallerClass(), filename);
} }
synchronized void load0(Class<?> fromClass, String filename) { synchronized void load0(Class<?> fromClass, String filename) {
@ -850,8 +853,9 @@ public class Runtime {
* @see java.lang.SecurityException * @see java.lang.SecurityException
* @see java.lang.SecurityManager#checkLink(java.lang.String) * @see java.lang.SecurityManager#checkLink(java.lang.String)
*/ */
@CallerSensitive
public void loadLibrary(String libname) { public void loadLibrary(String libname) {
loadLibrary0(System.getCallerClass(), libname); loadLibrary0(Reflection.getCallerClass(), libname);
} }
synchronized void loadLibrary0(Class<?> fromClass, String libname) { synchronized void loadLibrary0(Class<?> fromClass, String libname) {

View File

@ -36,10 +36,10 @@ import java.net.SocketPermission;
import java.net.NetPermission; import java.net.NetPermission;
import java.util.Hashtable; import java.util.Hashtable;
import java.net.InetAddress; import java.net.InetAddress;
import java.lang.reflect.Member;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.net.URL; import java.net.URL;
import sun.reflect.CallerSensitive;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
/** /**
@ -1679,6 +1679,7 @@ class SecurityManager {
* @since JDK1.1 * @since JDK1.1
* @see #checkPermission(java.security.Permission) checkPermission * @see #checkPermission(java.security.Permission) checkPermission
*/ */
@CallerSensitive
public void checkMemberAccess(Class<?> clazz, int which) { public void checkMemberAccess(Class<?> clazz, int which) {
if (clazz == null) { if (clazz == null) {
throw new NullPointerException("class can't be null"); throw new NullPointerException("class can't be null");

View File

@ -35,6 +35,7 @@ import java.security.AllPermission;
import java.nio.channels.Channel; import java.nio.channels.Channel;
import java.nio.channels.spi.SelectorProvider; import java.nio.channels.spi.SelectorProvider;
import sun.nio.ch.Interruptible; import sun.nio.ch.Interruptible;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import sun.reflect.annotation.AnnotationType; import sun.reflect.annotation.AnnotationType;
@ -1072,8 +1073,9 @@ public final class System {
* @see java.lang.Runtime#load(java.lang.String) * @see java.lang.Runtime#load(java.lang.String)
* @see java.lang.SecurityManager#checkLink(java.lang.String) * @see java.lang.SecurityManager#checkLink(java.lang.String)
*/ */
@CallerSensitive
public static void load(String filename) { public static void load(String filename) {
Runtime.getRuntime().load0(getCallerClass(), filename); Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
} }
/** /**
@ -1107,8 +1109,9 @@ public final class System {
* @see java.lang.Runtime#loadLibrary(java.lang.String) * @see java.lang.Runtime#loadLibrary(java.lang.String)
* @see java.lang.SecurityManager#checkLink(java.lang.String) * @see java.lang.SecurityManager#checkLink(java.lang.String)
*/ */
@CallerSensitive
public static void loadLibrary(String libname) { public static void loadLibrary(String libname) {
Runtime.getRuntime().loadLibrary0(getCallerClass(), libname); Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
} }
/** /**
@ -1245,10 +1248,4 @@ public final class System {
} }
}); });
} }
/* returns the class of the caller. */
static Class<?> getCallerClass() {
// NOTE use of more generic Reflection.getCallerClass()
return Reflection.getCallerClass(3);
}
} }

View File

@ -37,6 +37,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.LockSupport;
import sun.nio.ch.Interruptible; import sun.nio.ch.Interruptible;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
@ -1443,15 +1445,14 @@ class Thread implements Runnable {
* *
* @since 1.2 * @since 1.2
*/ */
@CallerSensitive
public ClassLoader getContextClassLoader() { public ClassLoader getContextClassLoader() {
if (contextClassLoader == null) if (contextClassLoader == null)
return null; return null;
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader(); ClassLoader.checkClassLoaderPermission(contextClassLoader,
if (ClassLoader.needsClassLoaderPermissionCheck(ccl, contextClassLoader)) { Reflection.getCallerClass());
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
} }
return contextClassLoader; return contextClassLoader;
} }

View File

@ -709,7 +709,9 @@ import jdk.internal.org.objectweb.asm.Type;
InvokerBytecodeGenerator.maybeDump(className, classFile); InvokerBytecodeGenerator.maybeDump(className, classFile);
Class<? extends BoundMethodHandle> bmhClass = Class<? extends BoundMethodHandle> bmhClass =
//UNSAFE.defineAnonymousClass(BoundMethodHandle.class, classFile, null).asSubclass(BoundMethodHandle.class); //UNSAFE.defineAnonymousClass(BoundMethodHandle.class, classFile, null).asSubclass(BoundMethodHandle.class);
UNSAFE.defineClass(className, classFile, 0, classFile.length).asSubclass(BoundMethodHandle.class); UNSAFE.defineClass(className, classFile, 0, classFile.length,
BoundMethodHandle.class.getClassLoader(), null)
.asSubclass(BoundMethodHandle.class);
UNSAFE.ensureClassInitialized(bmhClass); UNSAFE.ensureClassInitialized(bmhClass);
return bmhClass; return bmhClass;

View File

@ -394,7 +394,8 @@ import java.util.Objects;
IS_METHOD = MN_IS_METHOD, // method (not constructor) IS_METHOD = MN_IS_METHOD, // method (not constructor)
IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor
IS_FIELD = MN_IS_FIELD, // field IS_FIELD = MN_IS_FIELD, // field
IS_TYPE = MN_IS_TYPE; // nested type IS_TYPE = MN_IS_TYPE, // nested type
CALLER_SENSITIVE = MN_CALLER_SENSITIVE; // @CallerSensitive annotation detected
static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED; static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE; static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
@ -430,6 +431,10 @@ import java.util.Objects;
public boolean isPackage() { public boolean isPackage() {
return !testAnyFlags(ALL_ACCESS); return !testAnyFlags(ALL_ACCESS);
} }
/** Query whether this member has a CallerSensitive annotation. */
public boolean isCallerSensitive() {
return testAllFlags(CALLER_SENSITIVE);
}
/** Utility method to query whether this member is accessible from a given lookup class. */ /** Utility method to query whether this member is accessible from a given lookup class. */
public boolean isAccessibleFrom(Class<?> lookupClass) { public boolean isAccessibleFrom(Class<?> lookupClass) {

View File

@ -34,6 +34,8 @@ import sun.invoke.empty.Empty;
import sun.invoke.util.ValueConversions; import sun.invoke.util.ValueConversions;
import sun.invoke.util.VerifyType; import sun.invoke.util.VerifyType;
import sun.invoke.util.Wrapper; import sun.invoke.util.Wrapper;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import static java.lang.invoke.LambdaForm.*; import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
@ -891,9 +893,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
} }
} }
@CallerSensitive
private static boolean checkCallerClass(Class<?> expected, Class<?> expected2) { private static boolean checkCallerClass(Class<?> expected, Class<?> expected2) {
final int FRAME_COUNT_ARG = 2; // [0] Reflection [1] BindCaller [2] Expected // This method is called via MH_checkCallerClass and so it's
Class<?> actual = sun.reflect.Reflection.getCallerClass(FRAME_COUNT_ARG); // correct to ask for the immediate caller here.
Class<?> actual = Reflection.getCallerClass();
if (actual != expected && actual != expected2) if (actual != expected && actual != expected2)
throw new InternalError("found "+actual.getName()+", expected "+expected.getName() throw new InternalError("found "+actual.getName()+", expected "+expected.getName()
+(expected == expected2 ? "" : ", or else "+expected2.getName())); +(expected == expected2 ? "" : ", or else "+expected2.getName()));

View File

@ -26,7 +26,6 @@
package java.lang.invoke; package java.lang.invoke;
import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleStatics.*;
@ -34,7 +33,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
/** /**
* The JVM interface for the method handles package is all here. * The JVM interface for the method handles package is all here.
* This is an interface internal and private to an implemetantion of JSR 292. * This is an interface internal and private to an implementation of JSR 292.
* <em>This class is not part of the JSR 292 standard.</em> * <em>This class is not part of the JSR 292 standard.</em>
* @author jrose * @author jrose
*/ */
@ -101,6 +100,7 @@ class MethodHandleNatives {
MN_IS_CONSTRUCTOR = 0x00020000, // constructor MN_IS_CONSTRUCTOR = 0x00020000, // constructor
MN_IS_FIELD = 0x00040000, // field MN_IS_FIELD = 0x00040000, // field
MN_IS_TYPE = 0x00080000, // nested type MN_IS_TYPE = 0x00080000, // nested type
MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected
MN_REFERENCE_KIND_SHIFT = 24, // refKind MN_REFERENCE_KIND_SHIFT = 24, // refKind
MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT, MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
// The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers: // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
@ -391,129 +391,24 @@ class MethodHandleNatives {
* I.e., does it call Reflection.getCallerClass or a similer method * I.e., does it call Reflection.getCallerClass or a similer method
* to ask about the identity of its caller? * to ask about the identity of its caller?
*/ */
// FIXME: Replace this pattern match by an annotation @sun.reflect.CallerSensitive.
static boolean isCallerSensitive(MemberName mem) { static boolean isCallerSensitive(MemberName mem) {
if (!mem.isInvocable()) return false; // fields are not caller sensitive if (!mem.isInvocable()) return false; // fields are not caller sensitive
return mem.isCallerSensitive() || canBeCalledVirtual(mem);
}
static boolean canBeCalledVirtual(MemberName mem) {
assert(mem.isInvocable());
Class<?> defc = mem.getDeclaringClass(); Class<?> defc = mem.getDeclaringClass();
switch (mem.getName()) { switch (mem.getName()) {
case "doPrivileged":
case "doPrivilegedWithCombiner":
return defc == java.security.AccessController.class;
case "checkMemberAccess": case "checkMemberAccess":
return canBeCalledVirtual(mem, java.lang.SecurityManager.class); return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
case "getUnsafe":
return defc == sun.misc.Unsafe.class;
case "lookup":
return defc == java.lang.invoke.MethodHandles.class;
case "findStatic":
case "findVirtual":
case "findConstructor":
case "findSpecial":
case "findGetter":
case "findSetter":
case "findStaticGetter":
case "findStaticSetter":
case "bind":
case "unreflect":
case "unreflectSpecial":
case "unreflectConstructor":
case "unreflectGetter":
case "unreflectSetter":
return defc == java.lang.invoke.MethodHandles.Lookup.class;
case "invoke":
return defc == java.lang.reflect.Method.class;
case "get":
case "getBoolean":
case "getByte":
case "getChar":
case "getShort":
case "getInt":
case "getLong":
case "getFloat":
case "getDouble":
case "set":
case "setBoolean":
case "setByte":
case "setChar":
case "setShort":
case "setInt":
case "setLong":
case "setFloat":
case "setDouble":
return defc == java.lang.reflect.Field.class;
case "newInstance":
if (defc == java.lang.reflect.Constructor.class) return true;
if (defc == java.lang.Class.class) return true;
break;
case "forName":
case "getClassLoader":
case "getClasses":
case "getFields":
case "getMethods":
case "getConstructors":
case "getDeclaredClasses":
case "getDeclaredFields":
case "getDeclaredMethods":
case "getDeclaredConstructors":
case "getField":
case "getMethod":
case "getConstructor":
case "getDeclaredField":
case "getDeclaredMethod":
case "getDeclaredConstructor":
return defc == java.lang.Class.class;
case "getConnection":
case "getDriver":
case "getDrivers":
case "deregisterDriver":
return defc == getClass("java.sql.DriverManager");
case "newUpdater":
if (defc == java.util.concurrent.atomic.AtomicIntegerFieldUpdater.class) return true;
if (defc == java.util.concurrent.atomic.AtomicLongFieldUpdater.class) return true;
if (defc == java.util.concurrent.atomic.AtomicReferenceFieldUpdater.class) return true;
break;
case "getContextClassLoader": case "getContextClassLoader":
return canBeCalledVirtual(mem, java.lang.Thread.class); return canBeCalledVirtual(mem, java.lang.Thread.class);
case "getPackage":
case "getPackages":
return defc == java.lang.Package.class;
case "getParent":
case "getSystemClassLoader":
return defc == java.lang.ClassLoader.class;
case "load":
case "loadLibrary":
if (defc == java.lang.Runtime.class) return true;
if (defc == java.lang.System.class) return true;
break;
case "getCallerClass":
if (defc == sun.reflect.Reflection.class) return true;
if (defc == java.lang.System.class) return true;
break;
case "getCallerClassLoader":
return defc == java.lang.ClassLoader.class;
case "registerAsParallelCapable":
return canBeCalledVirtual(mem, java.lang.ClassLoader.class);
case "getProxyClass":
case "newProxyInstance":
return defc == java.lang.reflect.Proxy.class;
case "asInterfaceInstance":
return defc == java.lang.invoke.MethodHandleProxies.class;
case "getBundle":
case "clearCache":
return defc == java.util.ResourceBundle.class;
} }
return false; return false;
} }
// avoid static dependency to a class in other modules
private static Class<?> getClass(String cn) {
try {
return Class.forName(cn, false,
MethodHandleNatives.class.getClassLoader());
} catch (ClassNotFoundException e) {
throw new InternalError(e);
}
}
static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) { static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
Class<?> symbolicRefClass = symbolicRef.getDeclaringClass(); Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
if (symbolicRefClass == definingClass) return true; if (symbolicRefClass == definingClass) return true;

View File

@ -30,6 +30,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import sun.invoke.WrapperInstance; import sun.invoke.WrapperInstance;
import java.util.ArrayList; import java.util.ArrayList;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil; import sun.reflect.misc.ReflectUtil;
@ -137,14 +138,14 @@ public class MethodHandleProxies {
// entry points, must be covered by hand-written or automatically // entry points, must be covered by hand-written or automatically
// generated adapter classes. // generated adapter classes.
// //
@CallerSensitive
public static public static
<T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) { <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers())) if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
throw new IllegalArgumentException("not a public interface: "+intfc.getName()); throw new IllegalArgumentException("not a public interface: "+intfc.getName());
final MethodHandle mh; final MethodHandle mh;
if (System.getSecurityManager() != null) { if (System.getSecurityManager() != null) {
final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller final Class<?> caller = Reflection.getCallerClass();
final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
final ClassLoader ccl = caller != null ? caller.getClassLoader() : null; final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
ReflectUtil.checkProxyPackageAccess(ccl, intfc); ReflectUtil.checkProxyPackageAccess(ccl, intfc);
mh = ccl != null ? bindCaller(target, caller) : target; mh = ccl != null ? bindCaller(target, caller) : target;

View File

@ -26,13 +26,17 @@
package java.lang.invoke; package java.lang.invoke;
import java.lang.reflect.*; import java.lang.reflect.*;
import sun.invoke.util.ValueConversions; import java.security.AccessController;
import sun.invoke.util.VerifyAccess; import java.security.PrivilegedAction;
import sun.invoke.util.Wrapper;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import sun.invoke.util.ValueConversions;
import sun.invoke.util.VerifyAccess;
import sun.invoke.util.Wrapper;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleNatives.Constants.*;
@ -65,8 +69,9 @@ public class MethodHandles {
* This lookup object is a <em>capability</em> which may be delegated to trusted agents. * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
* Do not store it in place where untrusted code can access it. * Do not store it in place where untrusted code can access it.
*/ */
@CallerSensitive
public static Lookup lookup() { public static Lookup lookup() {
return new Lookup(); return new Lookup(Reflection.getCallerClass());
} }
/** /**
@ -416,18 +421,11 @@ public class MethodHandles {
* for method handle creation. * for method handle creation.
* Must be called by from a method in this package, * Must be called by from a method in this package,
* which in turn is called by a method not in this package. * which in turn is called by a method not in this package.
* <p>
* Also, don't make it private, lest javac interpose
* an access$N method.
*/ */
Lookup() {
this(getCallerClassAtEntryPoint(false), ALL_MODES);
// make sure we haven't accidentally picked up a privileged class:
checkUnprivilegedlookupClass(lookupClass);
}
Lookup(Class<?> lookupClass) { Lookup(Class<?> lookupClass) {
this(lookupClass, ALL_MODES); this(lookupClass, ALL_MODES);
// make sure we haven't accidentally picked up a privileged class:
checkUnprivilegedlookupClass(lookupClass);
} }
private Lookup(Class<?> lookupClass, int allowedModes) { private Lookup(Class<?> lookupClass, int allowedModes) {
@ -554,20 +552,6 @@ public class MethodHandles {
} }
} }
/* Obtain the external caller class, when called from Lookup.<init> or a first-level subroutine. */
private static Class<?> getCallerClassAtEntryPoint(boolean inSubroutine) {
final int CALLER_DEPTH = 4;
// Stack for the constructor entry point (inSubroutine=false):
// 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
// 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
// The stack is slightly different for a subroutine of a Lookup.find* method:
// 2: Lookup.*, 3: Lookup.find*.*, 4: caller
// Note: This should be the only use of getCallerClass in this file.
assert(Reflection.getCallerClass(CALLER_DEPTH-2) == Lookup.class);
assert(Reflection.getCallerClass(CALLER_DEPTH-1) == (inSubroutine ? Lookup.class : MethodHandles.class));
return Reflection.getCallerClass(CALLER_DEPTH);
}
/** /**
* Produces a method handle for a static method. * Produces a method handle for a static method.
* The type of the method handle will be that of the method. * The type of the method handle will be that of the method.
@ -594,12 +578,14 @@ public class MethodHandles {
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
@CallerSensitive
public public
MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type); MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor Class<?> callerClass = Reflection.getCallerClass();
Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor checkSecurityManager(refc, method, callerClass);
return getDirectMethod(REF_invokeStatic, refc, method, callerClass); return getDirectMethod(REF_invokeStatic, refc, method,
findBoundCallerClass(method, callerClass));
} }
/** /**
@ -645,6 +631,7 @@ public class MethodHandles {
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
@CallerSensitive
public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
if (refc == MethodHandle.class) { if (refc == MethodHandle.class) {
MethodHandle mh = findVirtualForMH(name, type); MethodHandle mh = findVirtualForMH(name, type);
@ -652,9 +639,10 @@ public class MethodHandles {
} }
byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual); byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
MemberName method = resolveOrFail(refKind, refc, name, type); MemberName method = resolveOrFail(refKind, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor Class<?> callerClass = Reflection.getCallerClass();
Class<?> callerClass = findBoundCallerClass(method); checkSecurityManager(refc, method, callerClass);
return getDirectMethod(refKind, refc, method, callerClass); return getDirectMethod(refKind, refc, method,
findBoundCallerClass(method, callerClass));
} }
private MethodHandle findVirtualForMH(String name, MethodType type) { private MethodHandle findVirtualForMH(String name, MethodType type) {
// these names require special lookups because of the implicit MethodType argument // these names require special lookups because of the implicit MethodType argument
@ -691,10 +679,11 @@ public class MethodHandles {
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
@CallerSensitive
public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException { public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
String name = "<init>"; String name = "<init>";
MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type); MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
checkSecurityManager(refc, ctor); // stack walk magic: do not refactor checkSecurityManager(refc, ctor, Reflection.getCallerClass());
return getDirectConstructor(refc, ctor); return getDirectConstructor(refc, ctor);
} }
@ -732,14 +721,16 @@ public class MethodHandles {
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
@CallerSensitive
public MethodHandle findSpecial(Class<?> refc, String name, MethodType type, public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException { Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
checkSpecialCaller(specialCaller); checkSpecialCaller(specialCaller);
Lookup specialLookup = this.in(specialCaller); Lookup specialLookup = this.in(specialCaller);
MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type); MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor Class<?> callerClass = Reflection.getCallerClass();
Class<?> callerClass = findBoundCallerClass(method); checkSecurityManager(refc, method, callerClass);
return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, callerClass); return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method,
findBoundCallerClass(method, callerClass));
} }
/** /**
@ -759,9 +750,10 @@ public class MethodHandles {
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
@CallerSensitive
public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException { public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(REF_getField, refc, name, type); MemberName field = resolveOrFail(REF_getField, refc, name, type);
checkSecurityManager(refc, field); // stack walk magic: do not refactor checkSecurityManager(refc, field, Reflection.getCallerClass());
return getDirectField(REF_getField, refc, field); return getDirectField(REF_getField, refc, field);
} }
@ -782,9 +774,10 @@ public class MethodHandles {
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
@CallerSensitive
public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException { public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(REF_putField, refc, name, type); MemberName field = resolveOrFail(REF_putField, refc, name, type);
checkSecurityManager(refc, field); // stack walk magic: do not refactor checkSecurityManager(refc, field, Reflection.getCallerClass());
return getDirectField(REF_putField, refc, field); return getDirectField(REF_putField, refc, field);
} }
@ -804,9 +797,10 @@ public class MethodHandles {
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
@CallerSensitive
public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException { public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(REF_getStatic, refc, name, type); MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
checkSecurityManager(refc, field); // stack walk magic: do not refactor checkSecurityManager(refc, field, Reflection.getCallerClass());
return getDirectField(REF_getStatic, refc, field); return getDirectField(REF_getStatic, refc, field);
} }
@ -826,9 +820,10 @@ public class MethodHandles {
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
@CallerSensitive
public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException { public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(REF_putStatic, refc, name, type); MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
checkSecurityManager(refc, field); // stack walk magic: do not refactor checkSecurityManager(refc, field, Reflection.getCallerClass());
return getDirectField(REF_putStatic, refc, field); return getDirectField(REF_putStatic, refc, field);
} }
@ -878,12 +873,14 @@ return mh1;
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
@CallerSensitive
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
Class<? extends Object> refc = receiver.getClass(); // may get NPE Class<? extends Object> refc = receiver.getClass(); // may get NPE
MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type); MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor Class<?> callerClass = Reflection.getCallerClass();
Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor checkSecurityManager(refc, method, callerClass);
MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, callerClass); MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method,
findBoundCallerClass(method, callerClass));
return mh.bindReceiver(receiver).setVarargs(method); return mh.bindReceiver(receiver).setVarargs(method);
} }
@ -908,13 +905,14 @@ return mh1;
* is set and {@code asVarargsCollector} fails * is set and {@code asVarargsCollector} fails
* @throws NullPointerException if the argument is null * @throws NullPointerException if the argument is null
*/ */
@CallerSensitive
public MethodHandle unreflect(Method m) throws IllegalAccessException { public MethodHandle unreflect(Method m) throws IllegalAccessException {
MemberName method = new MemberName(m); MemberName method = new MemberName(m);
byte refKind = method.getReferenceKind(); byte refKind = method.getReferenceKind();
if (refKind == REF_invokeSpecial) if (refKind == REF_invokeSpecial)
refKind = REF_invokeVirtual; refKind = REF_invokeVirtual;
assert(method.isMethod()); assert(method.isMethod());
Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor Class<?> callerClass = findBoundCallerClass(method, Reflection.getCallerClass());
Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this; Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, callerClass); return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, callerClass);
} }
@ -940,12 +938,13 @@ return mh1;
* is set and {@code asVarargsCollector} fails * is set and {@code asVarargsCollector} fails
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
@CallerSensitive
public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException { public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
checkSpecialCaller(specialCaller); checkSpecialCaller(specialCaller);
Lookup specialLookup = this.in(specialCaller); Lookup specialLookup = this.in(specialCaller);
MemberName method = new MemberName(m, true); MemberName method = new MemberName(m, true);
assert(method.isMethod()); assert(method.isMethod());
Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor Class<?> callerClass = findBoundCallerClass(method, Reflection.getCallerClass());
// ignore m.isAccessible: this is a new kind of access // ignore m.isAccessible: this is a new kind of access
return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, callerClass); return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, callerClass);
} }
@ -1050,20 +1049,35 @@ return mh1;
* If this lookup object has private access, then the caller class is the lookupClass. * If this lookup object has private access, then the caller class is the lookupClass.
* Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual). * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
* This is the same caller class as is used by checkSecurityManager. * This is the same caller class as is used by checkSecurityManager.
* This function performs stack walk magic: do not refactor it.
*/ */
Class<?> findBoundCallerClass(MemberName m) { Class<?> findBoundCallerClass(MemberName m, Class<?> callerAtEntryPoint) {
Class<?> callerClass = null; Class<?> callerClass = null;
if (MethodHandleNatives.isCallerSensitive(m)) { if (MethodHandleNatives.isCallerSensitive(m)) {
// Do not refactor this to a more "logical" place, since it is stack walk magic. // Do not refactor this to a more "logical" place, since it is stack walk magic.
// Note that this is the same expression as in Step 2 below in checkSecurityManager. // Note that this is the same expression as in Step 2 below in checkSecurityManager.
callerClass = ((allowedModes & PRIVATE) != 0 callerClass = ((allowedModes & PRIVATE) != 0
? lookupClass // for strong access modes, no extra check ? lookupClass // for strong access modes, no extra check
// next line does stack walk magic; do not refactor: : callerAtEntryPoint);
: getCallerClassAtEntryPoint(true));
} }
return callerClass; return callerClass;
} }
/**
* Determine whether a security manager has an overridden
* SecurityManager.checkMemberAccess method.
*/
private boolean isCheckMemberAccessOverridden(SecurityManager sm) {
final Class<? extends SecurityManager> cls = sm.getClass();
if (cls == SecurityManager.class) return false;
try {
return cls.getMethod("checkMemberAccess", Class.class, int.class).
getDeclaringClass() != SecurityManager.class;
} catch (NoSuchMethodException e) {
throw new InternalError("should not reach here");
}
}
/** /**
* Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>. * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
* Determines a trustable caller class to compare with refc, the symbolic reference class. * Determines a trustable caller class to compare with refc, the symbolic reference class.
@ -1071,46 +1085,55 @@ return mh1;
* Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual). * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
* This function performs stack walk magic: do not refactor it. * This function performs stack walk magic: do not refactor it.
*/ */
void checkSecurityManager(Class<?> refc, MemberName m) { void checkSecurityManager(Class<?> refc, MemberName m, Class<?> caller) {
SecurityManager smgr = System.getSecurityManager(); SecurityManager smgr = System.getSecurityManager();
if (smgr == null) return; if (smgr == null) return;
if (allowedModes == TRUSTED) return; if (allowedModes == TRUSTED) return;
final boolean overridden = isCheckMemberAccessOverridden(smgr);
// Step 1: // Step 1:
smgr.checkMemberAccess(refc, Member.PUBLIC); {
// Default policy is to allow Member.PUBLIC; no need to check
// permission if SecurityManager is the default implementation
final int which = Member.PUBLIC;
final Class<?> clazz = refc;
if (overridden) {
// Don't refactor; otherwise break the stack depth for
// checkMemberAccess of subclasses of SecurityManager as specified.
smgr.checkMemberAccess(clazz, which);
}
}
// Step 2: // Step 2:
Class<?> callerClass = ((allowedModes & PRIVATE) != 0 Class<?> callerClass = ((allowedModes & PRIVATE) != 0
? lookupClass // for strong access modes, no extra check ? lookupClass // for strong access modes, no extra check
// next line does stack walk magic; do not refactor: : caller);
: getCallerClassAtEntryPoint(true));
if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc) || if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc) ||
(callerClass != lookupClass && (callerClass != lookupClass &&
!VerifyAccess.classLoaderIsAncestor(callerClass, refc))) !VerifyAccess.classLoaderIsAncestor(callerClass, refc)))
smgr.checkPackageAccess(VerifyAccess.getPackageName(refc)); smgr.checkPackageAccess(VerifyAccess.getPackageName(refc));
// Step 3: // Step 3:
if (m.isPublic()) return; if (m.isPublic()) return;
Class<?> defc = m.getDeclaringClass(); Class<?> defc = m.getDeclaringClass();
smgr.checkMemberAccess(defc, Member.DECLARED); // STACK WALK HERE {
// Inline SecurityManager.checkMemberAccess
final int which = Member.DECLARED;
final Class<?> clazz = defc;
if (!overridden) {
if (caller.getClassLoader() != clazz.getClassLoader()) {
smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
}
} else {
// Don't refactor; otherwise break the stack depth for
// checkMemberAccess of subclasses of SecurityManager as specified.
smgr.checkMemberAccess(clazz, which);
}
}
// Step 4: // Step 4:
if (defc != refc) if (defc != refc)
smgr.checkPackageAccess(VerifyAccess.getPackageName(defc)); smgr.checkPackageAccess(VerifyAccess.getPackageName(defc));
// Comment from SM.checkMemberAccess, where which=DECLARED:
/*
* stack depth of 4 should be the caller of one of the
* methods in java.lang.Class that invoke checkMember
* access. The stack should look like:
*
* someCaller [3]
* java.lang.Class.someReflectionAPI [2]
* java.lang.Class.checkMemberAccess [1]
* SecurityManager.checkMemberAccess [0]
*
*/
// For us it is this stack:
// someCaller [3]
// Lookup.findSomeMember [2]
// Lookup.checkSecurityManager [1]
// SecurityManager.checkMemberAccess [0]
} }
void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException { void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
@ -1237,6 +1260,30 @@ return mh1;
checkMethod(refKind, refc, method); checkMethod(refKind, refc, method);
if (method.isMethodHandleInvoke()) if (method.isMethodHandleInvoke())
return fakeMethodHandleInvoke(method); return fakeMethodHandleInvoke(method);
Class<?> refcAsSuper;
if (refKind == REF_invokeSpecial &&
refc != lookupClass() &&
refc != (refcAsSuper = lookupClass().getSuperclass()) &&
refc.isAssignableFrom(lookupClass())) {
assert(!method.getName().equals("<init>")); // not this code path
// Per JVMS 6.5, desc. of invokespecial instruction:
// If the method is in a superclass of the LC,
// and if our original search was above LC.super,
// repeat the search (symbolic lookup) from LC.super.
// FIXME: MemberName.resolve should handle this instead.
MemberName m2 = new MemberName(refcAsSuper,
method.getName(),
method.getMethodType(),
REF_invokeSpecial);
m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
if (m2 == null) throw new InternalError(method.toString());
method = m2;
refc = refcAsSuper;
// redo basic checks
checkMethod(refKind, refc, method);
}
MethodHandle mh = DirectMethodHandle.make(refKind, refc, method); MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
mh = maybeBindCaller(method, mh, callerClass); mh = maybeBindCaller(method, mh, callerClass);
mh = mh.setVarargs(method); mh = mh.setVarargs(method);

View File

@ -38,9 +38,9 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
*/ */
static native void invokeFinalizeMethod(Object o) throws Throwable; static native void invokeFinalizeMethod(Object o) throws Throwable;
static private ReferenceQueue queue = new ReferenceQueue(); private static ReferenceQueue queue = new ReferenceQueue();
static private Finalizer unfinalized = null; private static Finalizer unfinalized = null;
static private Object lock = new Object(); private static final Object lock = new Object();
private Finalizer private Finalizer
next = null, next = null,
@ -142,7 +142,11 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
/* Called by Runtime.runFinalization() */ /* Called by Runtime.runFinalization() */
static void runFinalization() { static void runFinalization() {
forkSecondaryFinalizer(new Runnable() { forkSecondaryFinalizer(new Runnable() {
private volatile boolean running;
public void run() { public void run() {
if (running)
return;
running = true;
for (;;) { for (;;) {
Finalizer f = (Finalizer)queue.poll(); Finalizer f = (Finalizer)queue.poll();
if (f == null) break; if (f == null) break;
@ -155,7 +159,11 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
/* Invoked by java.lang.Shutdown */ /* Invoked by java.lang.Shutdown */
static void runAllFinalizers() { static void runAllFinalizers() {
forkSecondaryFinalizer(new Runnable() { forkSecondaryFinalizer(new Runnable() {
private volatile boolean running;
public void run() { public void run() {
if (running)
return;
running = true;
for (;;) { for (;;) {
Finalizer f; Finalizer f;
synchronized (lock) { synchronized (lock) {
@ -168,10 +176,14 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
} }
private static class FinalizerThread extends Thread { private static class FinalizerThread extends Thread {
private volatile boolean running;
FinalizerThread(ThreadGroup g) { FinalizerThread(ThreadGroup g) {
super(g, "Finalizer"); super(g, "Finalizer");
} }
public void run() { public void run() {
if (running)
return;
running = true;
for (;;) { for (;;) {
try { try {
Finalizer f = (Finalizer)queue.remove(); Finalizer f = (Finalizer)queue.remove();

View File

@ -25,6 +25,7 @@
package java.lang.reflect; package java.lang.reflect;
import sun.reflect.CallerSensitive;
import sun.reflect.ConstructorAccessor; import sun.reflect.ConstructorAccessor;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.reflect.generics.repository.ConstructorRepository; import sun.reflect.generics.repository.ConstructorRepository;
@ -392,14 +393,14 @@ public final class Constructor<T> extends Executable {
* @exception ExceptionInInitializerError if the initialization provoked * @exception ExceptionInInitializerError if the initialization provoked
* by this method fails. * by this method fails.
*/ */
@CallerSensitive
public T newInstance(Object ... initargs) public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException, throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException IllegalArgumentException, InvocationTargetException
{ {
if (!override) { if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass(2); Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, null, modifiers); checkAccess(caller, clazz, null, modifiers);
} }
} }

View File

@ -25,6 +25,7 @@
package java.lang.reflect; package java.lang.reflect;
import sun.reflect.CallerSensitive;
import sun.reflect.FieldAccessor; import sun.reflect.FieldAccessor;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.reflect.generics.repository.FieldRepository; import sun.reflect.generics.repository.FieldRepository;
@ -376,9 +377,16 @@ class Field extends AccessibleObject implements Member {
* @exception ExceptionInInitializerError if the initialization provoked * @exception ExceptionInInitializerError if the initialization provoked
* by this method fails. * by this method fails.
*/ */
@CallerSensitive
public Object get(Object obj) public Object get(Object obj)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).get(obj); return getFieldAccessor(obj).get(obj);
} }
@ -404,9 +412,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#get * @see Field#get
*/ */
@CallerSensitive
public boolean getBoolean(Object obj) public boolean getBoolean(Object obj)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getBoolean(obj); return getFieldAccessor(obj).getBoolean(obj);
} }
@ -432,9 +447,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#get * @see Field#get
*/ */
@CallerSensitive
public byte getByte(Object obj) public byte getByte(Object obj)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getByte(obj); return getFieldAccessor(obj).getByte(obj);
} }
@ -462,9 +484,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#get * @see Field#get
*/ */
@CallerSensitive
public char getChar(Object obj) public char getChar(Object obj)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getChar(obj); return getFieldAccessor(obj).getChar(obj);
} }
@ -492,9 +521,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#get * @see Field#get
*/ */
@CallerSensitive
public short getShort(Object obj) public short getShort(Object obj)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getShort(obj); return getFieldAccessor(obj).getShort(obj);
} }
@ -522,9 +558,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#get * @see Field#get
*/ */
@CallerSensitive
public int getInt(Object obj) public int getInt(Object obj)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getInt(obj); return getFieldAccessor(obj).getInt(obj);
} }
@ -552,9 +595,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#get * @see Field#get
*/ */
@CallerSensitive
public long getLong(Object obj) public long getLong(Object obj)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getLong(obj); return getFieldAccessor(obj).getLong(obj);
} }
@ -582,9 +632,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#get * @see Field#get
*/ */
@CallerSensitive
public float getFloat(Object obj) public float getFloat(Object obj)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getFloat(obj); return getFieldAccessor(obj).getFloat(obj);
} }
@ -612,9 +669,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#get * @see Field#get
*/ */
@CallerSensitive
public double getDouble(Object obj) public double getDouble(Object obj)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
return getFieldAccessor(obj).getDouble(obj); return getFieldAccessor(obj).getDouble(obj);
} }
@ -684,9 +748,16 @@ class Field extends AccessibleObject implements Member {
* @exception ExceptionInInitializerError if the initialization provoked * @exception ExceptionInInitializerError if the initialization provoked
* by this method fails. * by this method fails.
*/ */
@CallerSensitive
public void set(Object obj, Object value) public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).set(obj, value); getFieldAccessor(obj).set(obj, value);
} }
@ -714,9 +785,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#set * @see Field#set
*/ */
@CallerSensitive
public void setBoolean(Object obj, boolean z) public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setBoolean(obj, z); getFieldAccessor(obj).setBoolean(obj, z);
} }
@ -744,9 +822,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#set * @see Field#set
*/ */
@CallerSensitive
public void setByte(Object obj, byte b) public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setByte(obj, b); getFieldAccessor(obj).setByte(obj, b);
} }
@ -774,9 +859,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#set * @see Field#set
*/ */
@CallerSensitive
public void setChar(Object obj, char c) public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setChar(obj, c); getFieldAccessor(obj).setChar(obj, c);
} }
@ -804,9 +896,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#set * @see Field#set
*/ */
@CallerSensitive
public void setShort(Object obj, short s) public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setShort(obj, s); getFieldAccessor(obj).setShort(obj, s);
} }
@ -834,9 +933,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#set * @see Field#set
*/ */
@CallerSensitive
public void setInt(Object obj, int i) public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setInt(obj, i); getFieldAccessor(obj).setInt(obj, i);
} }
@ -864,9 +970,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#set * @see Field#set
*/ */
@CallerSensitive
public void setLong(Object obj, long l) public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setLong(obj, l); getFieldAccessor(obj).setLong(obj, l);
} }
@ -894,9 +1007,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#set * @see Field#set
*/ */
@CallerSensitive
public void setFloat(Object obj, float f) public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setFloat(obj, f); getFieldAccessor(obj).setFloat(obj, f);
} }
@ -924,17 +1044,23 @@ class Field extends AccessibleObject implements Member {
* by this method fails. * by this method fails.
* @see Field#set * @see Field#set
*/ */
@CallerSensitive
public void setDouble(Object obj, double d) public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException throws IllegalArgumentException, IllegalAccessException
{ {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).setDouble(obj, d); getFieldAccessor(obj).setDouble(obj, d);
} }
// Convenience routine which performs security checks // security check is done before calling this method
private FieldAccessor getFieldAccessor(Object obj) private FieldAccessor getFieldAccessor(Object obj)
throws IllegalAccessException throws IllegalAccessException
{ {
doSecurityCheck(obj);
boolean ov = override; boolean ov = override;
FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor; FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor;
return (a != null) ? a : acquireFieldAccessor(ov); return (a != null) ? a : acquireFieldAccessor(ov);
@ -982,19 +1108,6 @@ class Field extends AccessibleObject implements Member {
} }
} }
// NOTE: be very careful if you change the stack depth of this
// routine. The depth of the "getCallerClass" call is hardwired so
// that the compiler can have an easier time if this gets inlined.
private void doSecurityCheck(Object obj) throws IllegalAccessException {
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass(4);
checkAccess(caller, clazz, obj, modifiers);
}
}
}
/** /**
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
* @since 1.5 * @since 1.5

View File

@ -25,6 +25,7 @@
package java.lang.reflect; package java.lang.reflect;
import sun.reflect.CallerSensitive;
import sun.reflect.MethodAccessor; import sun.reflect.MethodAccessor;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.reflect.generics.repository.MethodRepository; import sun.reflect.generics.repository.MethodRepository;
@ -472,14 +473,14 @@ public final class Method extends Executable {
* @exception ExceptionInInitializerError if the initialization * @exception ExceptionInInitializerError if the initialization
* provoked by this method fails. * provoked by this method fails.
*/ */
@CallerSensitive
public Object invoke(Object obj, Object... args) public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException, throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException InvocationTargetException
{ {
if (!override) { if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass(1); Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers); checkAccess(caller, clazz, obj, modifiers);
} }
} }

View File

@ -39,6 +39,8 @@ import java.util.Set;
import java.util.List; import java.util.List;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import sun.misc.ProxyGenerator; import sun.misc.ProxyGenerator;
import sun.misc.VM;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil; import sun.reflect.misc.ReflectUtil;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
@ -408,28 +410,21 @@ public class Proxy implements java.io.Serializable {
* @throws NullPointerException if the {@code interfaces} array * @throws NullPointerException if the {@code interfaces} array
* argument or any of its elements are {@code null} * argument or any of its elements are {@code null}
*/ */
@CallerSensitive
public static Class<?> getProxyClass(ClassLoader loader, public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces) Class<?>... interfaces)
throws IllegalArgumentException throws IllegalArgumentException
{
return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
}
private static void checkProxyLoader(ClassLoader ccl,
ClassLoader loader)
{ {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
if (loader == null && ccl != null) { checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
if (!ProxyAccessHelper.allowNullLoader) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
} }
return getProxyClass0(loader, interfaces);
} }
/* /*
* Generate a proxy class (caller-sensitive). * Check permissions required to create a Proxy class.
* *
* To define a proxy class, it performs the access checks as in * To define a proxy class, it performs the access checks as in
* Class.forName (VM will invoke ClassLoader.checkPackageAccess): * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
@ -446,17 +441,28 @@ public class Proxy implements java.io.Serializable {
* will throw IllegalAccessError when the generated proxy class is * will throw IllegalAccessError when the generated proxy class is
* being defined via the defineClass0 method. * being defined via the defineClass0 method.
*/ */
private static Class<?> getProxyClass0(ClassLoader loader, private static void checkProxyAccess(Class<?> caller,
Class<?>... interfaces) { ClassLoader loader,
Class<?>... interfaces)
{
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller ClassLoader ccl = caller.getClassLoader();
final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME); if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
final ClassLoader ccl = caller.getClassLoader(); if (!ProxyAccessHelper.allowNullLoader) {
checkProxyLoader(ccl, loader); sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
ReflectUtil.checkProxyPackageAccess(ccl, interfaces); ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
} }
}
/**
* Generate a proxy class. Must call the checkProxyAccess method
* to perform permission checks before calling this.
*/
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
if (interfaces.length > 65535) { if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded"); throw new IllegalArgumentException("interface limit exceeded");
} }
@ -698,6 +704,7 @@ public class Proxy implements java.io.Serializable {
* if the invocation handler, {@code h}, is * if the invocation handler, {@code h}, is
* {@code null} * {@code null}
*/ */
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader, public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces, Class<?>[] interfaces,
InvocationHandler h) InvocationHandler h)
@ -707,10 +714,15 @@ public class Proxy implements java.io.Serializable {
throw new NullPointerException(); throw new NullPointerException();
} }
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
}
/* /*
* Look up or generate the designated proxy class. * Look up or generate the designated proxy class.
*/ */
Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor Class<?> cl = getProxyClass0(loader, interfaces);
/* /*
* Invoke its constructor with the designated invocation handler. * Invoke its constructor with the designated invocation handler.
@ -718,7 +730,6 @@ public class Proxy implements java.io.Serializable {
try { try {
final Constructor<?> cons = cl.getConstructor(constructorParams); final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h; final InvocationHandler ih = h;
SecurityManager sm = System.getSecurityManager();
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) { if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
// create proxy instance with doPrivilege as the proxy class may // create proxy instance with doPrivilege as the proxy class may
// implement non-public interfaces that requires a special permission // implement non-public interfaces that requires a special permission

View File

@ -122,7 +122,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
* not connected already. * not connected already.
*/ */
protected void disconnect() { protected void disconnect() {
disconnect0(connectedAddress.family); disconnect0(connectedAddress.holder().getFamily());
connected = false; connected = false;
connectedAddress = null; connectedAddress = null;
connectedPort = -1; connectedPort = -1;

View File

@ -100,27 +100,28 @@ class Inet4Address extends InetAddress {
Inet4Address() { Inet4Address() {
super(); super();
hostName = null; holder().hostName = null;
address = 0; holder().address = 0;
family = IPv4; holder().family = IPv4;
} }
Inet4Address(String hostName, byte addr[]) { Inet4Address(String hostName, byte addr[]) {
this.hostName = hostName; holder().hostName = hostName;
this.family = IPv4; holder().family = IPv4;
if (addr != null) { if (addr != null) {
if (addr.length == INADDRSZ) { if (addr.length == INADDRSZ) {
address = addr[3] & 0xFF; int address = addr[3] & 0xFF;
address |= ((addr[2] << 8) & 0xFF00); address |= ((addr[2] << 8) & 0xFF00);
address |= ((addr[1] << 16) & 0xFF0000); address |= ((addr[1] << 16) & 0xFF0000);
address |= ((addr[0] << 24) & 0xFF000000); address |= ((addr[0] << 24) & 0xFF000000);
holder().address = address;
} }
} }
} }
Inet4Address(String hostName, int address) { Inet4Address(String hostName, int address) {
this.hostName = hostName; holder().hostName = hostName;
this.family = IPv4; holder().family = IPv4;
this.address = address; holder().address = address;
} }
/** /**
@ -134,8 +135,8 @@ class Inet4Address extends InetAddress {
private Object writeReplace() throws ObjectStreamException { private Object writeReplace() throws ObjectStreamException {
// will replace the to be serialized 'this' object // will replace the to be serialized 'this' object
InetAddress inet = new InetAddress(); InetAddress inet = new InetAddress();
inet.hostName = this.hostName; inet.holder().hostName = holder().getHostName();
inet.address = this.address; inet.holder().address = holder().getAddress();
/** /**
* Prior to 1.4 an InetAddress was created with a family * Prior to 1.4 an InetAddress was created with a family
@ -143,7 +144,7 @@ class Inet4Address extends InetAddress {
* For compatibility reasons we must therefore write the * For compatibility reasons we must therefore write the
* the InetAddress with this family. * the InetAddress with this family.
*/ */
inet.family = 2; inet.holder().family = 2;
return inet; return inet;
} }
@ -157,7 +158,7 @@ class Inet4Address extends InetAddress {
* @since JDK1.1 * @since JDK1.1
*/ */
public boolean isMulticastAddress() { public boolean isMulticastAddress() {
return ((address & 0xf0000000) == 0xe0000000); return ((holder().getAddress() & 0xf0000000) == 0xe0000000);
} }
/** /**
@ -167,7 +168,7 @@ class Inet4Address extends InetAddress {
* @since 1.4 * @since 1.4
*/ */
public boolean isAnyLocalAddress() { public boolean isAnyLocalAddress() {
return address == 0; return holder().getAddress() == 0;
} }
/** /**
@ -195,6 +196,7 @@ class Inet4Address extends InetAddress {
// defined in "Documenting Special Use IPv4 Address Blocks // defined in "Documenting Special Use IPv4 Address Blocks
// that have been Registered with IANA" by Bill Manning // that have been Registered with IANA" by Bill Manning
// draft-manning-dsua-06.txt // draft-manning-dsua-06.txt
int address = holder().getAddress();
return (((address >>> 24) & 0xFF) == 169) return (((address >>> 24) & 0xFF) == 169)
&& (((address >>> 16) & 0xFF) == 254); && (((address >>> 16) & 0xFF) == 254);
} }
@ -211,6 +213,7 @@ class Inet4Address extends InetAddress {
// 10/8 prefix // 10/8 prefix
// 172.16/12 prefix // 172.16/12 prefix
// 192.168/16 prefix // 192.168/16 prefix
int address = holder().getAddress();
return (((address >>> 24) & 0xFF) == 10) return (((address >>> 24) & 0xFF) == 10)
|| ((((address >>> 24) & 0xFF) == 172) || ((((address >>> 24) & 0xFF) == 172)
&& (((address >>> 16) & 0xF0) == 16)) && (((address >>> 16) & 0xF0) == 16))
@ -257,6 +260,7 @@ class Inet4Address extends InetAddress {
*/ */
public boolean isMCLinkLocal() { public boolean isMCLinkLocal() {
// 224.0.0/24 prefix and ttl == 1 // 224.0.0/24 prefix and ttl == 1
int address = holder().getAddress();
return (((address >>> 24) & 0xFF) == 224) return (((address >>> 24) & 0xFF) == 224)
&& (((address >>> 16) & 0xFF) == 0) && (((address >>> 16) & 0xFF) == 0)
&& (((address >>> 8) & 0xFF) == 0); && (((address >>> 8) & 0xFF) == 0);
@ -272,6 +276,7 @@ class Inet4Address extends InetAddress {
*/ */
public boolean isMCSiteLocal() { public boolean isMCSiteLocal() {
// 239.255/16 prefix or ttl < 32 // 239.255/16 prefix or ttl < 32
int address = holder().getAddress();
return (((address >>> 24) & 0xFF) == 239) return (((address >>> 24) & 0xFF) == 239)
&& (((address >>> 16) & 0xFF) == 255); && (((address >>> 16) & 0xFF) == 255);
} }
@ -287,6 +292,7 @@ class Inet4Address extends InetAddress {
*/ */
public boolean isMCOrgLocal() { public boolean isMCOrgLocal() {
// 239.192 - 239.195 // 239.192 - 239.195
int address = holder().getAddress();
return (((address >>> 24) & 0xFF) == 239) return (((address >>> 24) & 0xFF) == 239)
&& (((address >>> 16) & 0xFF) >= 192) && (((address >>> 16) & 0xFF) >= 192)
&& (((address >>> 16) & 0xFF) <= 195); && (((address >>> 16) & 0xFF) <= 195);
@ -300,6 +306,7 @@ class Inet4Address extends InetAddress {
* @return the raw IP address of this object. * @return the raw IP address of this object.
*/ */
public byte[] getAddress() { public byte[] getAddress() {
int address = holder().getAddress();
byte[] addr = new byte[INADDRSZ]; byte[] addr = new byte[INADDRSZ];
addr[0] = (byte) ((address >>> 24) & 0xFF); addr[0] = (byte) ((address >>> 24) & 0xFF);
@ -325,7 +332,7 @@ class Inet4Address extends InetAddress {
* @return a hash code value for this IP address. * @return a hash code value for this IP address.
*/ */
public int hashCode() { public int hashCode() {
return address; return holder().getAddress();
} }
/** /**
@ -346,7 +353,7 @@ class Inet4Address extends InetAddress {
*/ */
public boolean equals(Object obj) { public boolean equals(Object obj) {
return (obj != null) && (obj instanceof Inet4Address) && return (obj != null) && (obj instanceof Inet4Address) &&
(((InetAddress)obj).address == address); (((InetAddress)obj).holder().getAddress() == holder().getAddress());
} }
// Utilities // Utilities

View File

@ -40,7 +40,7 @@ class Inet4AddressImpl implements InetAddressImpl {
public synchronized InetAddress anyLocalAddress() { public synchronized InetAddress anyLocalAddress() {
if (anyLocalAddress == null) { if (anyLocalAddress == null) {
anyLocalAddress = new Inet4Address(); // {0x00,0x00,0x00,0x00} anyLocalAddress = new Inet4Address(); // {0x00,0x00,0x00,0x00}
anyLocalAddress.hostName = "0.0.0.0"; anyLocalAddress.holder().hostName = "0.0.0.0";
} }
return anyLocalAddress; return anyLocalAddress;
} }

View File

@ -210,18 +210,18 @@ class Inet6Address extends InetAddress {
Inet6Address() { Inet6Address() {
super(); super();
hostName = null; holder().hostName = null;
ipaddress = new byte[INADDRSZ]; ipaddress = new byte[INADDRSZ];
family = IPv6; holder().family = IPv6;
} }
/* checking of value for scope_id should be done by caller /* checking of value for scope_id should be done by caller
* scope_id must be >= 0, or -1 to indicate not being set * scope_id must be >= 0, or -1 to indicate not being set
*/ */
Inet6Address(String hostName, byte addr[], int scope_id) { Inet6Address(String hostName, byte addr[], int scope_id) {
this.hostName = hostName; holder().hostName = hostName;
if (addr.length == INADDRSZ) { // normal IPv6 address if (addr.length == INADDRSZ) { // normal IPv6 address
family = IPv6; holder().family = IPv6;
ipaddress = addr.clone(); ipaddress = addr.clone();
} }
if (scope_id >= 0) { if (scope_id >= 0) {
@ -335,9 +335,9 @@ class Inet6Address extends InetAddress {
private void initif(String hostName, byte addr[],NetworkInterface nif) private void initif(String hostName, byte addr[],NetworkInterface nif)
throws UnknownHostException throws UnknownHostException
{ {
this.hostName = hostName; holder().hostName = hostName;
if (addr.length == INADDRSZ) { // normal IPv6 address if (addr.length == INADDRSZ) { // normal IPv6 address
family = IPv6; holder().family = IPv6;
ipaddress = addr.clone(); ipaddress = addr.clone();
} }
if (nif != null) { if (nif != null) {
@ -420,6 +420,11 @@ class Inet6Address extends InetAddress {
*/ */
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
if (getClass().getClassLoader() != null) {
throw new SecurityException ("invalid address type");
}
s.defaultReadObject(); s.defaultReadObject();
if (ifname != null && !ifname.equals("")) { if (ifname != null && !ifname.equals("")) {
@ -447,7 +452,7 @@ class Inet6Address extends InetAddress {
ipaddress.length); ipaddress.length);
} }
if (family != IPv6) { if (holder().getFamily() != IPv6) {
throw new InvalidObjectException("invalid address family type"); throw new InvalidObjectException("invalid address family type");
} }
} }

View File

@ -81,7 +81,7 @@ class Inet6AddressImpl implements InetAddressImpl {
if (anyLocalAddress == null) { if (anyLocalAddress == null) {
if (InetAddress.preferIPv6Address) { if (InetAddress.preferIPv6Address) {
anyLocalAddress = new Inet6Address(); anyLocalAddress = new Inet6Address();
anyLocalAddress.hostName = "::"; anyLocalAddress.holder().hostName = "::";
} else { } else {
anyLocalAddress = (new Inet4AddressImpl()).anyLocalAddress(); anyLocalAddress = (new Inet4AddressImpl()).anyLocalAddress();
} }

View File

@ -35,8 +35,12 @@ import java.util.ArrayList;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.security.AccessController; import java.security.AccessController;
import java.io.ObjectStreamException; import java.io.ObjectStreamException;
import java.io.ObjectStreamField;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectInputStream.GetField;
import java.io.ObjectOutputStream;
import java.io.ObjectOutputStream.PutField;
import sun.security.action.*; import sun.security.action.*;
import sun.net.InetAddressCachePolicy; import sun.net.InetAddressCachePolicy;
import sun.net.util.IPAddressUtil; import sun.net.util.IPAddressUtil;
@ -199,26 +203,49 @@ class InetAddress implements java.io.Serializable {
/* Specify address family preference */ /* Specify address family preference */
static transient boolean preferIPv6Address = false; static transient boolean preferIPv6Address = false;
/** static class InetAddressHolder {
* @serial
*/ InetAddressHolder() {}
InetAddressHolder(String hostName, int address, int family) {
this.hostName = hostName;
this.address = address;
this.family = family;
}
String hostName; String hostName;
String getHostName() {
return hostName;
}
/** /**
* Holds a 32-bit IPv4 address. * Holds a 32-bit IPv4 address.
*
* @serial
*/ */
int address; int address;
int getAddress() {
return address;
}
/** /**
* Specifies the address family type, for instance, '1' for IPv4 * Specifies the address family type, for instance, '1' for IPv4
* addresses, and '2' for IPv6 addresses. * addresses, and '2' for IPv6 addresses.
*
* @serial
*/ */
int family; int family;
int getFamily() {
return family;
}
}
/* Used to store the serializable fields of InetAddress */
private final transient InetAddressHolder holder;
InetAddressHolder holder() {
return holder;
}
/* Used to store the name service provider */ /* Used to store the name service provider */
private static List<NameService> nameServices = null; private static List<NameService> nameServices = null;
@ -251,6 +278,7 @@ class InetAddress implements java.io.Serializable {
* put in the address cache, since it is not created by name. * put in the address cache, since it is not created by name.
*/ */
InetAddress() { InetAddress() {
holder = new InetAddressHolder();
} }
/** /**
@ -263,7 +291,7 @@ class InetAddress implements java.io.Serializable {
*/ */
private Object readResolve() throws ObjectStreamException { private Object readResolve() throws ObjectStreamException {
// will replace the deserialized 'this' object // will replace the deserialized 'this' object
return new Inet4Address(this.hostName, this.address); return new Inet4Address(holder().getHostName(), holder().getAddress());
} }
/** /**
@ -500,10 +528,10 @@ class InetAddress implements java.io.Serializable {
* @see SecurityManager#checkConnect * @see SecurityManager#checkConnect
*/ */
String getHostName(boolean check) { String getHostName(boolean check) {
if (hostName == null) { if (holder().getHostName() == null) {
hostName = InetAddress.getHostFromNameService(this, check); holder().hostName = InetAddress.getHostFromNameService(this, check);
} }
return hostName; return holder().getHostName();
} }
/** /**
@ -666,6 +694,7 @@ class InetAddress implements java.io.Serializable {
* @return a string representation of this IP address. * @return a string representation of this IP address.
*/ */
public String toString() { public String toString() {
String hostName = holder().getHostName();
return ((hostName != null) ? hostName : "") return ((hostName != null) ? hostName : "")
+ "/" + getHostAddress(); + "/" + getHostAddress();
} }
@ -1522,14 +1551,58 @@ class InetAddress implements java.io.Serializable {
} }
} }
private static final long FIELDS_OFFSET;
private static final sun.misc.Unsafe UNSAFE;
static {
try {
sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
FIELDS_OFFSET = unsafe.objectFieldOffset(
InetAddress.class.getDeclaredField("holder")
);
UNSAFE = unsafe;
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private void readObject (ObjectInputStream s) throws private void readObject (ObjectInputStream s) throws
IOException, ClassNotFoundException { IOException, ClassNotFoundException {
s.defaultReadObject ();
if (getClass().getClassLoader() != null) { if (getClass().getClassLoader() != null) {
hostName = null;
address = 0;
throw new SecurityException ("invalid address type"); throw new SecurityException ("invalid address type");
} }
GetField gf = s.readFields();
String host = (String)gf.get("hostName", null);
int address= gf.get("address", 0);
int family= gf.get("family", 0);
InetAddressHolder h = new InetAddressHolder(host, address, family);
UNSAFE.putObject(this, FIELDS_OFFSET, h);
}
/* needed because the serializable fields no longer exist */
/**
* @serialField hostName String
* @serialField address int
* @serialField family int
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("hostName", String.class),
new ObjectStreamField("address", int.class),
new ObjectStreamField("family", int.class),
};
private void writeObject (ObjectOutputStream s) throws
IOException {
if (getClass().getClassLoader() != null) {
throw new SecurityException ("invalid address type");
}
PutField pf = s.putFields();
pf.put("hostName", holder().getHostName());
pf.put("address", holder().getAddress());
pf.put("family", holder().getFamily());
s.writeFields();
s.flush();
} }
} }

View File

@ -87,8 +87,8 @@ public class InetSocketAddress
if (hostname != null) if (hostname != null)
return hostname; return hostname;
if (addr != null) { if (addr != null) {
if (addr.hostName != null) if (addr.holder().getHostName() != null)
return addr.hostName; return addr.holder().getHostName();
else else
return addr.getHostAddress(); return addr.getHostAddress();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2013, 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
@ -120,6 +120,13 @@ public class LogStream extends PrintStream {
*/ */
@Deprecated @Deprecated
public static synchronized void setDefaultStream(PrintStream newDefault) { public static synchronized void setDefaultStream(PrintStream newDefault) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(
new java.util.logging.LoggingPermission("control", null));
}
defaultStream = newDefault; defaultStream = newDefault;
} }

View File

@ -26,6 +26,8 @@
package java.security; package java.security;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
/** /**
* <p> The AccessController class is used for access control operations * <p> The AccessController class is used for access control operations
@ -264,6 +266,7 @@ public final class AccessController {
* @see java.security.DomainCombiner * @see java.security.DomainCombiner
*/ */
@CallerSensitive
public static native <T> T doPrivileged(PrivilegedAction<T> action); public static native <T> T doPrivileged(PrivilegedAction<T> action);
/** /**
@ -288,14 +291,15 @@ public final class AccessController {
* *
* @since 1.6 * @since 1.6
*/ */
@CallerSensitive
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) { public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {
AccessControlContext acc = getStackAccessControlContext(); AccessControlContext acc = getStackAccessControlContext();
if (acc == null) { if (acc == null) {
return AccessController.doPrivileged(action); return AccessController.doPrivileged(action);
} }
DomainCombiner dc = acc.getAssignedCombiner(); DomainCombiner dc = acc.getAssignedCombiner();
return AccessController.doPrivileged(action, preserveCombiner(dc)); return AccessController.doPrivileged(action,
preserveCombiner(dc, Reflection.getCallerClass()));
} }
@ -326,6 +330,7 @@ public final class AccessController {
* @see #doPrivileged(PrivilegedAction) * @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*/ */
@CallerSensitive
public static native <T> T doPrivileged(PrivilegedAction<T> action, public static native <T> T doPrivileged(PrivilegedAction<T> action,
AccessControlContext context); AccessControlContext context);
@ -353,6 +358,7 @@ public final class AccessController {
* @see #doPrivilegedWithCombiner(PrivilegedExceptionAction) * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
* @see java.security.DomainCombiner * @see java.security.DomainCombiner
*/ */
@CallerSensitive
public static native <T> T public static native <T> T
doPrivileged(PrivilegedExceptionAction<T> action) doPrivileged(PrivilegedExceptionAction<T> action)
throws PrivilegedActionException; throws PrivilegedActionException;
@ -383,34 +389,29 @@ public final class AccessController {
* *
* @since 1.6 * @since 1.6
*/ */
public static <T> T doPrivilegedWithCombiner @CallerSensitive
(PrivilegedExceptionAction<T> action) throws PrivilegedActionException { public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action)
throws PrivilegedActionException
{
AccessControlContext acc = getStackAccessControlContext(); AccessControlContext acc = getStackAccessControlContext();
if (acc == null) { if (acc == null) {
return AccessController.doPrivileged(action); return AccessController.doPrivileged(action);
} }
DomainCombiner dc = acc.getAssignedCombiner(); DomainCombiner dc = acc.getAssignedCombiner();
return AccessController.doPrivileged(action, preserveCombiner(dc)); return AccessController.doPrivileged(action,
preserveCombiner(dc, Reflection.getCallerClass()));
} }
/** /**
* preserve the combiner across the doPrivileged call * preserve the combiner across the doPrivileged call
*/ */
private static AccessControlContext preserveCombiner private static AccessControlContext preserveCombiner(DomainCombiner combiner,
(DomainCombiner combiner) { Class<?> caller)
{
/**
* callerClass[0] = Reflection.getCallerClass
* callerClass[1] = AccessController.preserveCombiner
* callerClass[2] = AccessController.doPrivileged
* callerClass[3] = caller
*/
final Class<?> callerClass = sun.reflect.Reflection.getCallerClass(3);
ProtectionDomain callerPd = doPrivileged ProtectionDomain callerPd = doPrivileged
(new PrivilegedAction<ProtectionDomain>() { (new PrivilegedAction<ProtectionDomain>() {
public ProtectionDomain run() { public ProtectionDomain run() {
return callerClass.getProtectionDomain(); return caller.getProtectionDomain();
} }
}); });
@ -455,6 +456,7 @@ public final class AccessController {
* @see #doPrivileged(PrivilegedAction) * @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*/ */
@CallerSensitive
public static native <T> T public static native <T> T
doPrivileged(PrivilegedExceptionAction<T> action, doPrivileged(PrivilegedExceptionAction<T> action,
AccessControlContext context) AccessControlContext context)

View File

@ -30,6 +30,7 @@ import java.util.ServiceLoader;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection; import sun.reflect.Reflection;
@ -192,14 +193,11 @@ public class DriverManager {
* has been exceeded and has at least tried to cancel the * has been exceeded and has at least tried to cancel the
* current database connection attempt * current database connection attempt
*/ */
@CallerSensitive
public static Connection getConnection(String url, public static Connection getConnection(String url,
java.util.Properties info) throws SQLException { java.util.Properties info) throws SQLException {
// Gets the classloader of the code that called this method, may return (getConnection(url, info, Reflection.getCallerClass()));
// be null.
ClassLoader callerCL = DriverManager.getCallerClassLoader();
return (getConnection(url, info, callerCL));
} }
/** /**
@ -226,14 +224,11 @@ public class DriverManager {
* has been exceeded and has at least tried to cancel the * has been exceeded and has at least tried to cancel the
* current database connection attempt * current database connection attempt
*/ */
@CallerSensitive
public static Connection getConnection(String url, public static Connection getConnection(String url,
String user, String password) throws SQLException { String user, String password) throws SQLException {
java.util.Properties info = new java.util.Properties(); java.util.Properties info = new java.util.Properties();
// Gets the classloader of the code that called this method, may
// be null.
ClassLoader callerCL = DriverManager.getCallerClassLoader();
if (user != null) { if (user != null) {
info.put("user", user); info.put("user", user);
} }
@ -241,7 +236,7 @@ public class DriverManager {
info.put("password", password); info.put("password", password);
} }
return (getConnection(url, info, callerCL)); return (getConnection(url, info, Reflection.getCallerClass()));
} }
/** /**
@ -259,16 +254,12 @@ public class DriverManager {
* has been exceeded and has at least tried to cancel the * has been exceeded and has at least tried to cancel the
* current database connection attempt * current database connection attempt
*/ */
@CallerSensitive
public static Connection getConnection(String url) public static Connection getConnection(String url)
throws SQLException { throws SQLException {
java.util.Properties info = new java.util.Properties(); java.util.Properties info = new java.util.Properties();
return (getConnection(url, info, Reflection.getCallerClass()));
// Gets the classloader of the code that called this method, may
// be null.
ClassLoader callerCL = DriverManager.getCallerClassLoader();
return (getConnection(url, info, callerCL));
} }
/** /**
@ -282,21 +273,20 @@ public class DriverManager {
* that can connect to the given URL * that can connect to the given URL
* @exception SQLException if a database access error occurs * @exception SQLException if a database access error occurs
*/ */
@CallerSensitive
public static Driver getDriver(String url) public static Driver getDriver(String url)
throws SQLException { throws SQLException {
println("DriverManager.getDriver(\"" + url + "\")"); println("DriverManager.getDriver(\"" + url + "\")");
// Gets the classloader of the code that called this method, may Class<?> callerClass = Reflection.getCallerClass();
// be null.
ClassLoader callerCL = DriverManager.getCallerClassLoader();
// Walk through the loaded registeredDrivers attempting to locate someone // Walk through the loaded registeredDrivers attempting to locate someone
// who understands the given URL. // who understands the given URL.
for (DriverInfo aDriver : registeredDrivers) { for (DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then // If the caller does not have permission to load the driver then
// skip it. // skip it.
if(isDriverAllowed(aDriver.driver, callerCL)) { if(isDriverAllowed(aDriver.driver, callerClass)) {
try { try {
if(aDriver.driver.acceptsURL(url)) { if(aDriver.driver.acceptsURL(url)) {
// Success! // Success!
@ -350,20 +340,18 @@ public class DriverManager {
* @param driver the JDBC Driver to drop * @param driver the JDBC Driver to drop
* @exception SQLException if a database access error occurs * @exception SQLException if a database access error occurs
*/ */
@CallerSensitive
public static synchronized void deregisterDriver(Driver driver) public static synchronized void deregisterDriver(Driver driver)
throws SQLException { throws SQLException {
if (driver == null) { if (driver == null) {
return; return;
} }
// Gets the classloader of the code that called this method,
// may be null.
ClassLoader callerCL = DriverManager.getCallerClassLoader();
println("DriverManager.deregisterDriver: " + driver); println("DriverManager.deregisterDriver: " + driver);
DriverInfo aDriver = new DriverInfo(driver); DriverInfo aDriver = new DriverInfo(driver);
if(registeredDrivers.contains(aDriver)) { if(registeredDrivers.contains(aDriver)) {
if (isDriverAllowed(driver, callerCL)) { if (isDriverAllowed(driver, Reflection.getCallerClass())) {
registeredDrivers.remove(aDriver); registeredDrivers.remove(aDriver);
} else { } else {
// If the caller does not have permission to load the driver then // If the caller does not have permission to load the driver then
@ -384,18 +372,17 @@ public class DriverManager {
* *
* @return the list of JDBC Drivers loaded by the caller's class loader * @return the list of JDBC Drivers loaded by the caller's class loader
*/ */
@CallerSensitive
public static java.util.Enumeration<Driver> getDrivers() { public static java.util.Enumeration<Driver> getDrivers() {
java.util.Vector<Driver> result = new java.util.Vector<>(); java.util.Vector<Driver> result = new java.util.Vector<>();
// Gets the classloader of the code that called this method, may Class<?> callerClass = Reflection.getCallerClass();
// be null.
ClassLoader callerCL = DriverManager.getCallerClassLoader();
// Walk through the loaded registeredDrivers. // Walk through the loaded registeredDrivers.
for(DriverInfo aDriver : registeredDrivers) { for(DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then // If the caller does not have permission to load the driver then
// skip it. // skip it.
if(isDriverAllowed(aDriver.driver, callerCL)) { if(isDriverAllowed(aDriver.driver, callerClass)) {
result.addElement(aDriver.driver); result.addElement(aDriver.driver);
} else { } else {
println(" skipping: " + aDriver.getClass().getName()); println(" skipping: " + aDriver.getClass().getName());
@ -493,17 +480,13 @@ public class DriverManager {
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Internal method used to get the caller's class loader.
// Replaces the call to the native method
private static ClassLoader getCallerClassLoader() {
Class<?> cc = Reflection.getCallerClass(3);
ClassLoader cl = (cc != null) ? cc.getClassLoader() : null;
return cl;
}
// Indicates whether the class object that would be created if the code calling // Indicates whether the class object that would be created if the code calling
// DriverManager is accessible. // DriverManager is accessible.
private static boolean isDriverAllowed(Driver driver, Class<?> caller) {
ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
return isDriverAllowed(driver, callerCL);
}
private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) { private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
boolean result = false; boolean result = false;
if(driver != null) { if(driver != null) {
@ -556,7 +539,7 @@ public class DriverManager {
*/ */
try{ try{
while(driversIterator.hasNext()) { while(driversIterator.hasNext()) {
println(" Loading done by the java.util.ServiceLoader : "+driversIterator.next()); driversIterator.next();
} }
} catch(Throwable t) { } catch(Throwable t) {
// Do nothing // Do nothing
@ -586,13 +569,14 @@ public class DriverManager {
// Worker method called by the public getConnection() methods. // Worker method called by the public getConnection() methods.
private static Connection getConnection( private static Connection getConnection(
String url, java.util.Properties info, ClassLoader callerCL) throws SQLException { String url, java.util.Properties info, Class<?> caller) throws SQLException {
/* /*
* When callerCl is null, we should check the application's * When callerCl is null, we should check the application's
* (which is invoking this class indirectly) * (which is invoking this class indirectly)
* classloader, so that the JDBC driver class outside rt.jar * classloader, so that the JDBC driver class outside rt.jar
* can be loaded from here. * can be loaded from here.
*/ */
ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
synchronized(DriverManager.class) { synchronized(DriverManager.class) {
// synchronize loading of the correct classloader. // synchronize loading of the correct classloader.
if (callerCL == null) { if (callerCL == null) {

View File

@ -28,6 +28,9 @@ import java.io.Serializable;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
/** /**
* This class consists exclusively of static methods that operate on or return * This class consists exclusively of static methods that operate on or return
@ -264,8 +267,7 @@ public class Collections {
} }
private static <T> private static <T>
int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
{
int low = 0; int low = 0;
int high = list.size()-1; int high = list.size()-1;
@ -441,21 +443,21 @@ public class Collections {
/** /**
* Randomly permutes the specified list using a default source of * Randomly permutes the specified list using a default source of
* randomness. All permutations occur with approximately equal * randomness. All permutations occur with approximately equal
* likelihood.<p> * likelihood.
* *
* The hedge "approximately" is used in the foregoing description because * <p>The hedge "approximately" is used in the foregoing description because
* default source of randomness is only approximately an unbiased source * default source of randomness is only approximately an unbiased source
* of independently chosen bits. If it were a perfect source of randomly * of independently chosen bits. If it were a perfect source of randomly
* chosen bits, then the algorithm would choose permutations with perfect * chosen bits, then the algorithm would choose permutations with perfect
* uniformity.<p> * uniformity.
* *
* This implementation traverses the list backwards, from the last element * <p>This implementation traverses the list backwards, from the last
* up to the second, repeatedly swapping a randomly selected element into * element up to the second, repeatedly swapping a randomly selected element
* the "current position". Elements are randomly selected from the * into the "current position". Elements are randomly selected from the
* portion of the list that runs from the first element to the current * portion of the list that runs from the first element to the current
* position, inclusive.<p> * position, inclusive.
* *
* This method runs in linear time. If the specified list does not * <p>This method runs in linear time. If the specified list does not
* implement the {@link RandomAccess} interface and is large, this * implement the {@link RandomAccess} interface and is large, this
* implementation dumps the specified list into an array before shuffling * implementation dumps the specified list into an array before shuffling
* it, and dumps the shuffled array back into the list. This avoids the * it, and dumps the shuffled array back into the list. This avoids the
@ -469,9 +471,10 @@ public class Collections {
public static void shuffle(List<?> list) { public static void shuffle(List<?> list) {
Random rnd = r; Random rnd = r;
if (rnd == null) if (rnd == null)
r = rnd = new Random(); r = rnd = new Random(); // harmless race.
shuffle(list, rnd); shuffle(list, rnd);
} }
private static Random r; private static Random r;
/** /**
@ -1391,6 +1394,67 @@ public class Collections {
public int hashCode() {return m.hashCode();} public int hashCode() {return m.hashCode();}
public String toString() {return m.toString();} public String toString() {return m.toString();}
// Override default methods in Map
@Override
@SuppressWarnings("unchecked")
public V getOrDefault(Object k, V defaultValue) {
// Safe cast as we don't change the value
return ((Map<K, V>)m).getOrDefault(k, defaultValue);
}
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
m.forEach(action);
}
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
throw new UnsupportedOperationException();
}
@Override
public V putIfAbsent(K key, V value) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object key, Object value) {
throw new UnsupportedOperationException();
}
@Override
public boolean replace(K key, V oldValue, V newValue) {
throw new UnsupportedOperationException();
}
@Override
public V replace(K key, V value) {
throw new UnsupportedOperationException();
}
@Override
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
throw new UnsupportedOperationException();
}
@Override
public V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
@Override
public V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
@Override
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
/** /**
* We need this class in addition to UnmodifiableSet as * We need this class in addition to UnmodifiableSet as
* Map.Entries themselves permit modification of the backing Map * Map.Entries themselves permit modification of the backing Map
@ -1590,9 +1654,9 @@ public class Collections {
* </pre> * </pre>
* Failure to follow this advice may result in non-deterministic behavior. * Failure to follow this advice may result in non-deterministic behavior.
* *
* <p>The returned collection does <i>not</i> pass the <tt>hashCode</tt> * <p>The returned collection does <i>not</i> pass the {@code hashCode}
* and <tt>equals</tt> operations through to the backing collection, but * and {@code equals} operations through to the backing collection, but
* relies on <tt>Object</tt>'s equals and hashCode methods. This is * relies on {@code Object}'s equals and hashCode methods. This is
* necessary to preserve the contracts of these operations in the case * necessary to preserve the contracts of these operations in the case
* that the backing collection is a set or a list.<p> * that the backing collection is a set or a list.<p>
* *
@ -2107,6 +2171,57 @@ public class Collections {
public String toString() { public String toString() {
synchronized (mutex) {return m.toString();} synchronized (mutex) {return m.toString();}
} }
// Override default methods in Map
@Override
public V getOrDefault(Object k, V defaultValue) {
synchronized (mutex) {return m.getOrDefault(k, defaultValue);}
}
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
synchronized (mutex) {m.forEach(action);}
}
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
synchronized (mutex) {m.replaceAll(function);}
}
@Override
public V putIfAbsent(K key, V value) {
synchronized (mutex) {return m.putIfAbsent(key, value);}
}
@Override
public boolean remove(Object key, Object value) {
synchronized (mutex) {return m.remove(key, value);}
}
@Override
public boolean replace(K key, V oldValue, V newValue) {
synchronized (mutex) {return m.replace(key, oldValue, newValue);}
}
@Override
public V replace(K key, V value) {
synchronized (mutex) {return m.replace(key, value);}
}
@Override
public V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
synchronized (mutex) {return m.computeIfAbsent(key, mappingFunction);}
}
@Override
public V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
synchronized (mutex) {return m.computeIfPresent(key, remappingFunction);}
}
@Override
public V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
synchronized (mutex) {return m.compute(key, remappingFunction);}
}
@Override
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
synchronized (mutex) {return m.merge(key, value, remappingFunction);}
}
private void writeObject(ObjectOutputStream s) throws IOException { private void writeObject(ObjectOutputStream s) throws IOException {
synchronized (mutex) {s.defaultWriteObject();} synchronized (mutex) {s.defaultWriteObject();}
} }
@ -2326,6 +2441,8 @@ public class Collections {
} }
public Iterator<E> iterator() { public Iterator<E> iterator() {
// JDK-6363904 - unwrapped iterator could be typecast to
// ListIterator with unsafe set()
final Iterator<E> it = c.iterator(); final Iterator<E> it = c.iterator();
return new Iterator<E>() { return new Iterator<E>() {
public boolean hasNext() { return it.hasNext(); } public boolean hasNext() { return it.hasNext(); }
@ -2717,6 +2834,16 @@ public class Collections {
throw new ClassCastException(badValueMsg(value)); throw new ClassCastException(badValueMsg(value));
} }
private BiFunction<? super K, ? super V, ? extends V> typeCheck(
BiFunction<? super K, ? super V, ? extends V> func) {
Objects.requireNonNull(func);
return (k, v) -> {
V newValue = func.apply(k, v);
typeCheck(k, newValue);
return newValue;
};
}
private String badKeyMsg(Object key) { private String badKeyMsg(Object key) {
return "Attempt to insert " + key.getClass() + return "Attempt to insert " + key.getClass() +
" key into map with key type " + keyType; " key into map with key type " + keyType;
@ -2782,6 +2909,74 @@ public class Collections {
return entrySet; return entrySet;
} }
// Override default methods in Map
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
m.forEach(action);
}
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
m.replaceAll(typeCheck(function));
}
@Override
public V putIfAbsent(K key, V value) {
typeCheck(key, value);
return m.putIfAbsent(key, value);
}
@Override
public boolean remove(Object key, Object value) {
return m.remove(key, value);
}
@Override
public boolean replace(K key, V oldValue, V newValue) {
typeCheck(key, newValue);
return m.replace(key, oldValue, newValue);
}
@Override
public V replace(K key, V value) {
typeCheck(key, value);
return m.replace(key, value);
}
@Override
public V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
return m.computeIfAbsent(key, k -> {
V value = mappingFunction.apply(k);
typeCheck(k, value);
return value;
});
}
@Override
public V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
return m.computeIfPresent(key, typeCheck(remappingFunction));
}
@Override
public V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
return m.compute(key, typeCheck(remappingFunction));
}
@Override
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
return m.merge(key, value, (v1, v2) -> {
V newValue = remappingFunction.apply(v1, v2);
typeCheck(null, newValue);
return newValue;
});
}
/** /**
* We need this class in addition to CheckedSet as Map.Entry permits * We need this class in addition to CheckedSet as Map.Entry permits
* modification of the backing Map via the setValue operation. This * modification of the backing Map via the setValue operation. This
@ -3456,6 +3651,67 @@ public class Collections {
public int hashCode() {return 0;} public int hashCode() {return 0;}
// Override default methods in Map
@Override
@SuppressWarnings("unchecked")
public V getOrDefault(Object k, V defaultValue) {
return defaultValue;
}
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
}
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
Objects.requireNonNull(function);
}
@Override
public V putIfAbsent(K key, V value) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object key, Object value) {
throw new UnsupportedOperationException();
}
@Override
public boolean replace(K key, V oldValue, V newValue) {
throw new UnsupportedOperationException();
}
@Override
public V replace(K key, V value) {
throw new UnsupportedOperationException();
}
@Override
public V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
throw new UnsupportedOperationException();
}
@Override
public V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
@Override
public V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
@Override
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
// Preserves singleton property // Preserves singleton property
private Object readResolve() { private Object readResolve() {
return EMPTY_MAP; return EMPTY_MAP;
@ -3619,6 +3875,65 @@ public class Collections {
return values; return values;
} }
// Override default methods in Map
@Override
public V getOrDefault(Object key, V defaultValue) {
return eq(key, k) ? v : defaultValue;
}
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
action.accept(k, v);
}
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
throw new UnsupportedOperationException();
}
@Override
public V putIfAbsent(K key, V value) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object key, Object value) {
throw new UnsupportedOperationException();
}
@Override
public boolean replace(K key, V oldValue, V newValue) {
throw new UnsupportedOperationException();
}
@Override
public V replace(K key, V value) {
throw new UnsupportedOperationException();
}
@Override
public V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
throw new UnsupportedOperationException();
}
@Override
public V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
@Override
public V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
@Override
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
} }
// Miscellaneous // Miscellaneous

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2000, 2013, 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
@ -28,7 +28,7 @@ formatVersion=1
# Version of the currency code information in this class. # Version of the currency code information in this class.
# It is a serial number that accompanies with each amendment. # It is a serial number that accompanies with each amendment.
dataVersion=154 dataVersion=155
# List of all valid ISO 4217 currency codes. # List of all valid ISO 4217 currency codes.
# To ensure compatibility, do not remove codes. # To ensure compatibility, do not remove codes.
@ -585,7 +585,7 @@ ZW=ZWL
minor0=\ minor0=\
ADP-BEF-BIF-BYB-BYR-CLF-CLP-DJF-ESP-GNF-\ ADP-BEF-BIF-BYB-BYR-CLF-CLP-DJF-ESP-GNF-\
GRD-ISK-ITL-JPY-KMF-KRW-LUF-MGF-PYG-PTE-RWF-\ GRD-ISK-ITL-JPY-KMF-KRW-LUF-MGF-PYG-PTE-RWF-\
TPE-TRL-VND-VUV-XAF-XOF-XPF TPE-TRL-UGX-VND-VUV-XAF-XOF-XPF
minor1= minor1=
minor3=\ minor3=\
BHD-IQD-JOD-KWD-LYD-OMR-TND BHD-IQD-JOD-KWD-LYD-OMR-TND

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, 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,7 +24,11 @@
*/ */
package java.util; package java.util;
import java.io.*; import java.io.*;
import java.util.function.Consumer;
import java.util.function.BiFunction;
import java.util.function.Function;
/** /**
* Hash table based implementation of the <tt>Map</tt> interface. This * Hash table based implementation of the <tt>Map</tt> interface. This
@ -376,6 +380,13 @@ public class HashMap<K,V>
return null == entry ? null : entry.getValue(); return null == entry ? null : entry.getValue();
} }
@Override
public V getOrDefault(Object key, V defaultValue) {
Entry<K,V> entry = getEntry(key);
return (entry == null) ? defaultValue : entry.getValue();
}
/** /**
* Returns <tt>true</tt> if this map contains a mapping for the * Returns <tt>true</tt> if this map contains a mapping for the
* specified key. * specified key.
@ -603,6 +614,261 @@ public class HashMap<K,V>
return (e == null ? null : e.value); return (e == null ? null : e.value);
} }
// optimized implementations of default methods in Map
@Override
public V putIfAbsent(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)table[i];
for(; e != null; e = e.next) {
if (e.hash == hash && Objects.equals(e.key, key)) {
if(e.value != null) {
return e.value;
}
e.value = value;
modCount++;
e.recordAccess(this);
return null;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
@Override
public boolean remove(Object key, Object value) {
if (isEmpty()) {
return false;
}
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
@SuppressWarnings("unchecked")
Entry<K,V> prev = (Entry<K,V>)table[i];
Entry<K,V> e = prev;
while (e != null) {
Entry<K,V> next = e.next;
if (e.hash == hash && Objects.equals(e.key, key)) {
if (!Objects.equals(e.value, value)) {
return false;
}
modCount++;
size--;
if (prev == e)
table[i] = next;
else
prev.next = next;
e.recordRemoval(this);
return true;
}
prev = e;
e = next;
}
return false;
}
@Override
public boolean replace(K key, V oldValue, V newValue) {
if (isEmpty()) {
return false;
}
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)table[i];
for (; e != null; e = e.next) {
if (e.hash == hash && Objects.equals(e.key, key) && Objects.equals(e.value, oldValue)) {
e.value = newValue;
e.recordAccess(this);
return true;
}
}
return false;
}
@Override
public V replace(K key, V value) {
if (isEmpty()) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)table[i];
for (; e != null; e = e.next) {
if (e.hash == hash && Objects.equals(e.key, key)) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
return null;
}
@Override
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)table[i];
for (; e != null; e = e.next) {
if (e.hash == hash && Objects.equals(e.key, key)) {
V oldValue = e.value;
return oldValue == null ? (e.value = mappingFunction.apply(key)) : oldValue;
}
}
V newValue = mappingFunction.apply(key);
if (newValue != null) {
modCount++;
addEntry(hash, key, newValue, i);
}
return newValue;
}
@Override
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
if (isEmpty()) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
@SuppressWarnings("unchecked")
Entry<K,V> prev = (Entry<K,V>)table[i];
Entry<K,V> e = prev;
while (e != null) {
Entry<K,V> next = e.next;
if (e.hash == hash && Objects.equals(e.key, key)) {
V oldValue = e.value;
if (oldValue == null)
break;
V newValue = remappingFunction.apply(key, oldValue);
modCount++;
if (newValue == null) {
size--;
if (prev == e)
table[i] = next;
else
prev.next = next;
e.recordRemoval(this);
} else {
e.value = newValue;
e.recordAccess(this);
}
return newValue;
}
prev = e;
e = next;
}
return null;
}
@Override
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
@SuppressWarnings("unchecked")
Entry<K,V> prev = (Entry<K,V>)table[i];
Entry<K,V> e = prev;
while (e != null) {
Entry<K,V> next = e.next;
if (e.hash == hash && Objects.equals(e.key, key)) {
V oldValue = e.value;
V newValue = remappingFunction.apply(key, oldValue);
if (newValue != oldValue) {
modCount++;
if (newValue == null) {
size--;
if (prev == e)
table[i] = next;
else
prev.next = next;
e.recordRemoval(this);
} else {
e.value = newValue;
e.recordAccess(this);
}
}
return newValue;
}
prev = e;
e = next;
}
V newValue = remappingFunction.apply(key, null);
if (newValue != null) {
modCount++;
addEntry(hash, key, newValue, i);
}
return newValue;
}
@Override
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
@SuppressWarnings("unchecked")
Entry<K,V> prev = (Entry<K,V>)table[i];
Entry<K,V> e = prev;
while (e != null) {
Entry<K,V> next = e.next;
if (e.hash == hash && Objects.equals(e.key, key)) {
V oldValue = e.value;
V newValue = remappingFunction.apply(oldValue, value);
modCount++;
if (newValue == null) {
size--;
if (prev == e)
table[i] = next;
else
prev.next = next;
e.recordRemoval(this);
} else {
e.value = newValue;
e.recordAccess(this);
}
return newValue;
}
prev = e;
e = next;
}
if (value != null) {
modCount++;
addEntry(hash, key, value, i);
}
return value;
}
// end of optimized implementations of default methods in Map
/** /**
* Removes and returns the entry associated with the specified key * Removes and returns the entry associated with the specified key
* in the HashMap. Returns null if the HashMap contains no mapping * in the HashMap. Returns null if the HashMap contains no mapping

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2013, 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,7 +24,11 @@
*/ */
package java.util; package java.util;
import java.io.*; import java.io.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.BiFunction;
/** /**
* This class implements a hash table, which maps keys to values. Any * This class implements a hash table, which maps keys to values. Any
@ -455,6 +459,26 @@ public class Hashtable<K,V>
} }
} }
private void addEntry(int hash, K key, V value, int index) {
modCount++;
Entry<?,?> tab[] = table;
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
hash = hash(key);
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) tab[index];
tab[index] = new Entry<>(hash, key, value, e);
count++;
}
/** /**
* Maps the specified <code>key</code> to the specified * Maps the specified <code>key</code> to the specified
* <code>value</code> in this hashtable. Neither the key nor the * <code>value</code> in this hashtable. Neither the key nor the
@ -492,21 +516,7 @@ public class Hashtable<K,V>
} }
} }
modCount++; addEntry(hash, key, value, index);
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
hash = hash(key);
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
tab[index] = new Entry<>(hash, key, value, e);
count++;
return null; return null;
} }
@ -892,6 +902,239 @@ public class Hashtable<K,V>
return h; return h;
} }
@Override
public synchronized V getOrDefault(Object key, V defaultValue) {
V result = get(key);
return (null == result) ? defaultValue : result;
}
@Override
public synchronized void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action); // explicit check required in case
// table is empty.
Entry<?,?>[] tab = table;
for (Entry<?,?> entry : tab) {
while (entry != null) {
action.accept((K)entry.key, (V)entry.value);
entry = entry.next;
}
}
}
@Override
public synchronized void replaceAll(
BiFunction<? super K, ? super V, ? extends V> function) {
Map.super.replaceAll(function);
}
@Override
public synchronized V putIfAbsent(K key, V value) {
Objects.requireNonNull(value);
// Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
for (; entry != null; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
if (old == null) {
entry.value = value;
}
return old;
}
}
addEntry(hash, key, value, index);
return null;
}
@Override
public synchronized boolean remove(Object key, Object value) {
Objects.requireNonNull(value);
Entry<?,?> tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
if ((e.hash == hash) && e.key.equals(key) && e.value.equals(value)) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
e.value = null;
return true;
}
}
return false;
}
@Override
public synchronized boolean replace(K key, V oldValue, V newValue) {
Entry<?,?> tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (; e != null; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
if (e.value.equals(oldValue)) {
e.value = newValue;
return true;
} else {
return false;
}
}
}
return false;
}
@Override
public synchronized V replace(K key, V value) {
Entry<?,?> tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (; e != null; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
return null;
}
@Override
public synchronized V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
Entry<?,?> tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (; e != null; e = e.next) {
if (e.hash == hash && e.key.equals(key)) {
// Hashtable not accept null value
return e.value;
}
}
V newValue = mappingFunction.apply(key);
if (newValue != null) {
addEntry(hash, key, newValue, index);
}
return newValue;
}
@Override
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Entry<?,?> tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
if (e.hash == hash && e.key.equals(key)) {
V newValue = remappingFunction.apply(key, e.value);
if (newValue == null) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
} else {
e.value = newValue;
}
return newValue;
}
}
return null;
}
@Override
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Entry<?,?> tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
if (e.hash == hash && Objects.equals(e.key, key)) {
V newValue = remappingFunction.apply(key, e.value);
if (newValue == null) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
} else {
e.value = newValue;
}
return newValue;
}
}
V newValue = remappingFunction.apply(key, null);
if (newValue != null) {
addEntry(hash, key, newValue, index);
}
return newValue;
}
@Override
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Entry<?,?> tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
if (e.hash == hash && e.key.equals(key)) {
V newValue = remappingFunction.apply(e.value, value);
if (newValue == null) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
} else {
e.value = newValue;
}
return newValue;
}
}
if (value != null) {
addEntry(hash, key, value, index);
}
return value;
}
/** /**
* Save the state of the Hashtable to a stream (i.e., serialize it). * Save the state of the Hashtable to a stream (i.e., serialize it).
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, 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
@ -25,6 +25,10 @@
package java.util; package java.util;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
/** /**
* An object that maps keys to values. A map cannot contain duplicate keys; * An object that maps keys to values. A map cannot contain duplicate keys;
* each key can map to at most one value. * each key can map to at most one value.
@ -475,4 +479,613 @@ public interface Map<K,V> {
*/ */
int hashCode(); int hashCode();
// Defaultable methods
/**
* Returns the value to which the specified key is mapped,
* or {@code defaultValue} if this map contains no mapping
* for the key.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties.
*
* @param key the key whose associated value is to be returned
* @return the value to which the specified key is mapped, or
* {@code defaultValue} if this map contains no mapping for the key
* @throws ClassCastException if the key is of an inappropriate type for
* this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified key is null and this map
* does not permit null keys
* (<a href="Collection.html#optional-restrictions">optional</a>)
*/
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
/**
* Performs the given action on each entry in this map, in the order entries
* are returned by an entry set iterator (which may be unspecified), until
* all entries have been processed or the action throws an {@code Exception}.
* Exceptions thrown by the action are relayed to the caller.
*
* <p>The default implementation should be overridden by implementations if
* they can provide a more performant implementation than an iterator-based
* one.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties.
*
* @implSpec The default implementation is equivalent to, for this
* {@code map}:
* <pre> {@code
* for ((Map.Entry<K, V> entry : map.entrySet())
* action.accept(entry.getKey(), entry.getValue());
* }</pre>
*
* @param action The action to be performed for each entry
* @throws NullPointerException if the specified action is null
* @throws ConcurrentModificationException if an entry is found to be
* removed during iteration
* @since 1.8
*/
default void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
}
/**
* Replaces each entry's value with the result of invoking the given
* function on that entry, in the order entries are returned by an entry
* set iterator, until all entries have been processed or the function
* throws an exception.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties.
*
* @implSpec
* <p>The default implementation is equivalent to, for this {@code map}:
* <pre> {@code
* for ((Map.Entry<K, V> entry : map.entrySet())
* entry.setValue(function.apply(entry.getKey(), entry.getValue()));
* }</pre>
*
* @param function the function to apply to each entry
* @throws UnsupportedOperationException if the {@code set} operation
* is not supported by this map's entry set iterator.
* @throws ClassCastException if the class of a replacement value
* prevents it from being stored in this map
* @throws NullPointerException if the specified function is null, or the
* specified replacement value is null, and this map does not permit null
* values
* @throws ClassCastException if a replacement value is of an inappropriate
* type for this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if function or a replacement value is null,
* and this map does not permit null keys or values
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws IllegalArgumentException if some property of a replacement value
* prevents it from being stored in this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ConcurrentModificationException if an entry is found to be
* removed during iteration
* @since 1.8
*/
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
Objects.requireNonNull(function);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
throw new ConcurrentModificationException(ise);
}
entry.setValue(function.apply(k, v));
}
}
/**
* If the specified key is not already associated with a value (or is mapped
* to {@code null}) associates it with the given value and returns
* {@code null}, else returns the current value.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties.
*
* @implSpec
* The default implementation is equivalent to, for this {@code
* map}:
*
* <pre> {@code
* if (map.get(key) == null)
* return map.put(key, value);
* else
* return map.get(key);
* }</pre>
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with the specified key, or
* {@code 1} if there was no mapping for the key.
* (A {@code null} return can also indicate that the map
* previously associated {@code null} with the key,
* if the implementation supports null values.)
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if the key or value is of an inappropriate
* type for this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified key or value is null,
* and this map does not permit null keys or values
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws IllegalArgumentException if some property of the specified key
* or value prevents it from being stored in this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ConcurrentModificationException if a modification of the map is
* detected during insertion of the value.
* @since 1.8
*/
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) {
if (put(key, value) != null) {
throw new ConcurrentModificationException();
}
}
return v;
}
/**
* Removes the entry for the specified key only if it is currently
* mapped to the specified value.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties.
*
* @implSpec
* The default implementation is equivalent to, for this {@code map}:
*
* <pre> {@code
* if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
* map.remove(key);
* return true;
* } else
* return false;
* }</pre>
*
* @param key key with which the specified value is associated
* @param value value expected to be associated with the specified key
* @return {@code true} if the value was removed
* @throws UnsupportedOperationException if the {@code remove} operation
* is not supported by this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if the key or value is of an inappropriate
* type for this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified key or value is null,
* and this map does not permit null keys or values
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @since 1.8
*/
default boolean remove(Object key, Object value) {
Object curValue = get(key);
if (!Objects.equals(curValue, value) ||
(curValue == null && !containsKey(key))) {
return false;
}
remove(key);
return true;
}
/**
* Replaces the entry for the specified key only if currently
* mapped to the specified value.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties.
*
* @implSpec
* The default implementation is equivalent to, for this {@code map}:
*
* <pre> {@code
* if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
* map.put(key, newValue);
* return true;
* } else
* return false;
* }</pre>
*
* @param key key with which the specified value is associated
* @param oldValue value expected to be associated with the specified key
* @param newValue value to be associated with the specified key
* @return {@code true} if the value was replaced
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if the class of a specified key or value
* prevents it from being stored in this map
* @throws NullPointerException if a specified key or value is null,
* and this map does not permit null keys or values
* @throws IllegalArgumentException if some property of a specified key
* or value prevents it from being stored in this map
* @since 1.8
*/
default boolean replace(K key, V oldValue, V newValue) {
Object curValue = get(key);
if (!Objects.equals(curValue, oldValue) ||
(curValue == null && !containsKey(key))) {
return false;
}
put(key, newValue);
return true;
}
/**
* Replaces the entry for the specified key only if it is
* currently mapped to some value.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties.
*
* @implSpec
* The default implementation is equivalent to, for this {@code map}:
*
* <pre> {@code
* if (map.containsKey(key)) {
* return map.put(key, value);
* } else
* return null;
* }</pre>
*
* @param key key with which the specified value is associated
* @param value value to be associated with the specified key
* @return the previous value associated with the specified key, or
* {@code null} if there was no mapping for the key.
* (A {@code null} return can also indicate that the map
* previously associated {@code null} with the key,
* if the implementation supports null values.)
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified key or value is null,
* and this map does not permit null keys or values
* @throws IllegalArgumentException if some property of the specified key
* or value prevents it from being stored in this map
* @since 1.8
*/
default V replace(K key, V value) {
return containsKey(key) ? put(key, value) : null;
}
/**
* If the specified key is not already associated with a value (or
* is mapped to {@code null}), attempts to compute its value using
* the given mapping function and enters it into this map unless
* {@code null}.
*
* <p>If the function returns {@code null} no mapping is recorded. If
* the function itself throws an (unchecked) exception, the
* exception is rethrown, and no mapping is recorded. The most
* common usage is to construct a new object serving as an initial
* mapped value or memoized result, as in:
*
* <pre> {@code
* map.computeIfAbsent(key, k -> new Value(f(k)));
* }</pre>
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties. In particular, all implementations of
* subinterface {@link java.util.concurrent.ConcurrentMap} must document
* whether the function is applied once atomically only if the value is not
* present. Any class that permits null values must document
* whether and how this method distinguishes absence from null mappings.
*
* @implSpec
* The default implementation is equivalent to the following
* steps for this {@code map}, then returning the current value or
* {@code null} if now absent:
*
* <pre> {@code
* if (map.get(key) == null) {
* V newValue = mappingFunction.apply(key);
* if (newValue != null)
* map.putIfAbsent(key, newValue);
* }
* }</pre>
*
* @param key key with which the specified value is to be associated
* @param mappingFunction the function to compute a value
* @return the current (existing or computed) value associated with
* the specified key, or null if the computed value is null
* @throws NullPointerException if the specified key is null and
* this map does not support null keys, or the
* mappingFunction is null
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @since 1.8
*/
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
V v, newValue;
return ((v = get(key)) == null &&
(newValue = mappingFunction.apply(key)) != null &&
(v = putIfAbsent(key, newValue)) == null) ? newValue : v;
}
/**
* If the value for the specified key is present and non-null, attempts to
* compute a new mapping given the key and its current mapped value.
*
* <p>If the function returns {@code null}, the mapping is removed. If the
* function itself throws an (unchecked) exception, the exception is
* rethrown, and the current mapping is left unchanged.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties. In particular, all implementations of
* subinterface {@link java.util.concurrent.ConcurrentMap} must document
* whether the function is applied once atomically only if the value is not
* present. Any class that permits null values must document
* whether and how this method distinguishes absence from null mappings.
*
* @implSpec
* The default implementation is equivalent to performing the
* following steps for this {@code map}, then returning the
* current value or {@code null} if now absent:
*
* <pre> {@code
* if (map.get(key) != null) {
* V oldValue = map.get(key);
* V newValue = remappingFunction.apply(key, oldValue);
* if (newValue != null)
* map.replace(key, oldValue, newValue);
* else
* map.remove(key, oldValue);
* }
* }</pre>
*
* In concurrent contexts, the default implementation may retry
* these steps when multiple threads attempt updates.
*
* @param key key with which the specified value is to be associated
* @param remappingFunction the function to compute a value
* @return the new value associated with the specified key, or null if none
* @throws NullPointerException if the specified key is null and
* this map does not support null keys, or the
* remappingFunction is null
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @since 1.8
*/
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
V oldValue;
while ((oldValue = get(key)) != null) {
V newValue = remappingFunction.apply(key, oldValue);
if (newValue != null) {
if (replace(key, oldValue, newValue))
return newValue;
} else if (remove(key, oldValue))
return null;
}
return oldValue;
}
/**
* Attempts to compute a mapping for the specified key and its
* current mapped value (or {@code null} if there is no current
* mapping). For example, to either create or append a {@code
* String msg} to a value mapping:
*
* <pre> {@code
* map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre>
* (Method {@link #merge merge()} is often simpler to use for such purposes.)
*
* <p>If the function returns {@code null}, the mapping is removed (or
* remains absent if initially absent). If the function itself throws an
* (unchecked) exception, the exception is rethrown, and the current mapping
* is left unchanged.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties. In particular, all implementations of
* subinterface {@link java.util.concurrent.ConcurrentMap} must document
* whether the function is applied once atomically only if the value is not
* present. Any class that permits null values must document
* whether and how this method distinguishes absence from null mappings.
*
* @implSpec
* The default implementation is equivalent to performing the following
* steps for this {@code map}, then returning the current value or
* {@code null} if absent:
*
* <pre> {@code
* V oldValue = map.get(key);
* V newValue = remappingFunction.apply(key, oldValue);
* if (oldValue != null ) {
* if (newValue != null)
* map.replace(key, oldValue, newValue);
* else
* map.remove(key, oldValue);
* } else {
* if (newValue != null)
* map.putIfAbsent(key, newValue);
* else
* return null;
* }
* }</pre>
*
* In concurrent contexts, the default implementation may retry
* these steps when multiple threads attempt updates.
*
* @param key key with which the specified value is to be associated
* @param remappingFunction the function to compute a value
* @return the new value associated with the specified key, or null if none
* @throws NullPointerException if the specified key is null and
* this map does not support null keys, or the
* remappingFunction is null
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @since 1.8
*/
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
V oldValue = get(key);
for (;;) {
V newValue = remappingFunction.apply(key, oldValue);
if (oldValue != null) {
if (newValue != null) {
if (replace(key, oldValue, newValue))
return newValue;
} else if (remove(key, oldValue)) {
return null;
}
oldValue = get(key);
} else {
if (newValue != null) {
if ((oldValue = putIfAbsent(key, newValue)) == null)
return newValue;
} else {
return null;
}
}
}
}
/**
* If the specified key is not already associated with a value or is
* associated with null, associates it with the given value.
* Otherwise, replaces the value with the results of the given
* remapping function, or removes if the result is {@code null}. This
* method may be of use when combining multiple mapped values for a key.
* For example, to either create or append a {@code String msg} to a
* value mapping:
*
* <pre> {@code
* map.merge(key, msg, String::concat)
* }</pre>
*
* <p>If the function returns {@code null}, the mapping is removed (or
* remains absent if initially absent). If the function itself throws an
* (unchecked) exception, the exception is rethrown, and the current mapping
* is left unchanged.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties. In particular, all implementations of
* subinterface {@link java.util.concurrent.ConcurrentMap} must document
* whether the function is applied once atomically only if the value is not
* present. Any class that permits null values must document
* whether and how this method distinguishes absence from null mappings.
*
* @implSpec
* The default implementation is equivalent to performing the
* following steps for this {@code map}, then returning the
* current value or {@code null} if absent:
*
* <pre> {@code
* V oldValue = map.get(key);
* V newValue = (oldValue == null) ? value :
* remappingFunction.apply(oldValue, value);
* if (newValue == null)
* map.remove(key, oldValue);
* else if (oldValue == null)
* map.putIfAbsent(key, newValue);
* else
* map.replace(key, oldValue, newValue);
* }</pre>
*
* In concurrent contexts, the default implementation may retry
* these steps when multiple threads attempt updates.
*
* @param key key with which the specified value is to be associated
* @param value the value to use if absent
* @param remappingFunction the function to recompute a value if present
* @return the new value associated with the specified key, or null if none
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified key is null and
* this map does not support null keys, or the
* remappingFunction is null
* @since 1.8
*/
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
V oldValue = get(key);
for (;;) {
if (oldValue != null) {
V newValue = remappingFunction.apply(oldValue, value);
if (newValue != null) {
if (replace(key, oldValue, newValue))
return newValue;
} else if (remove(key, oldValue)) {
return null;
}
oldValue = get(key);
} else {
if (value == null) {
return null;
}
if ((oldValue = putIfAbsent(key, value)) == null) {
return value;
}
}
}
}
} }

View File

@ -57,6 +57,8 @@ import java.util.concurrent.ConcurrentMap;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.spi.ResourceBundleControlProvider; import java.util.spi.ResourceBundleControlProvider;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.util.locale.BaseLocale; import sun.util.locale.BaseLocale;
import sun.util.locale.LocaleObjectCache; import sun.util.locale.LocaleObjectCache;
@ -440,14 +442,10 @@ public abstract class ResourceBundle {
/* /*
* Automatic determination of the ClassLoader to be used to load * Automatic determination of the ClassLoader to be used to load
* resources on behalf of the client. N.B. The client is getLoader's * resources on behalf of the client.
* caller's caller.
*/ */
private static ClassLoader getLoader() { private static ClassLoader getLoader(Class<?> caller) {
Class<?>[] stack = getClassContext(); ClassLoader cl = caller == null ? null : caller.getClassLoader();
/* Magic number 2 identifies our caller's caller */
Class<?> c = stack[2];
ClassLoader cl = (c == null) ? null : c.getClassLoader();
if (cl == null) { if (cl == null) {
// When the caller's loader is the boot class loader, cl is null // When the caller's loader is the boot class loader, cl is null
// here. In that case, ClassLoader.getSystemClassLoader() may // here. In that case, ClassLoader.getSystemClassLoader() may
@ -461,8 +459,6 @@ public abstract class ResourceBundle {
return cl; return cl;
} }
private static native Class<?>[] getClassContext();
/** /**
* A wrapper of ClassLoader.getSystemClassLoader(). * A wrapper of ClassLoader.getSystemClassLoader().
*/ */
@ -746,11 +742,11 @@ public abstract class ResourceBundle {
* if no resource bundle for the specified base name can be found * if no resource bundle for the specified base name can be found
* @return a resource bundle for the given base name and the default locale * @return a resource bundle for the given base name and the default locale
*/ */
@CallerSensitive
public static final ResourceBundle getBundle(String baseName) public static final ResourceBundle getBundle(String baseName)
{ {
return getBundleImpl(baseName, Locale.getDefault(), return getBundleImpl(baseName, Locale.getDefault(),
/* must determine loader here, else we break stack invariant */ getLoader(Reflection.getCallerClass()),
getLoader(),
getDefaultControl(baseName)); getDefaultControl(baseName));
} }
@ -788,11 +784,11 @@ public abstract class ResourceBundle {
* needed. * needed.
* @since 1.6 * @since 1.6
*/ */
@CallerSensitive
public static final ResourceBundle getBundle(String baseName, public static final ResourceBundle getBundle(String baseName,
Control control) { Control control) {
return getBundleImpl(baseName, Locale.getDefault(), return getBundleImpl(baseName, Locale.getDefault(),
/* must determine loader here, else we break stack invariant */ getLoader(Reflection.getCallerClass()),
getLoader(),
control); control);
} }
@ -817,12 +813,12 @@ public abstract class ResourceBundle {
* if no resource bundle for the specified base name can be found * if no resource bundle for the specified base name can be found
* @return a resource bundle for the given base name and locale * @return a resource bundle for the given base name and locale
*/ */
@CallerSensitive
public static final ResourceBundle getBundle(String baseName, public static final ResourceBundle getBundle(String baseName,
Locale locale) Locale locale)
{ {
return getBundleImpl(baseName, locale, return getBundleImpl(baseName, locale,
/* must determine loader here, else we break stack invariant */ getLoader(Reflection.getCallerClass()),
getLoader(),
getDefaultControl(baseName)); getDefaultControl(baseName));
} }
@ -863,11 +859,11 @@ public abstract class ResourceBundle {
* needed. * needed.
* @since 1.6 * @since 1.6
*/ */
@CallerSensitive
public static final ResourceBundle getBundle(String baseName, Locale targetLocale, public static final ResourceBundle getBundle(String baseName, Locale targetLocale,
Control control) { Control control) {
return getBundleImpl(baseName, targetLocale, return getBundleImpl(baseName, targetLocale,
/* must determine loader here, else we break stack invariant */ getLoader(Reflection.getCallerClass()),
getLoader(),
control); control);
} }
@ -1721,8 +1717,9 @@ public abstract class ResourceBundle {
* @since 1.6 * @since 1.6
* @see ResourceBundle.Control#getTimeToLive(String,Locale) * @see ResourceBundle.Control#getTimeToLive(String,Locale)
*/ */
@CallerSensitive
public static final void clearCache() { public static final void clearCache() {
clearCache(getLoader()); clearCache(getLoader(Reflection.getCallerClass()));
} }
/** /**

View File

@ -34,6 +34,7 @@
*/ */
package java.util.concurrent; package java.util.concurrent;
import java.io.ObjectInputStream;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.*;
import java.util.*; import java.util.*;
import java.io.Serializable; import java.io.Serializable;
@ -1483,7 +1484,23 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void readObject(java.io.ObjectInputStream s) private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject(); // Don't call defaultReadObject()
ObjectInputStream.GetField oisFields = s.readFields();
final Segment<K,V>[] oisSegments = (Segment<K,V>[])oisFields.get("segments", null);
final int ssize = oisSegments.length;
if (ssize < 1 || ssize > MAX_SEGMENTS
|| (ssize & (ssize-1)) != 0 ) // ssize not power of two
throw new java.io.InvalidObjectException("Bad number of segments:"
+ ssize);
int sshift = 0, ssizeTmp = ssize;
while (ssizeTmp > 1) {
++sshift;
ssizeTmp >>>= 1;
}
UNSAFE.putIntVolatile(this, SEGSHIFT_OFFSET, 32 - sshift);
UNSAFE.putIntVolatile(this, SEGMASK_OFFSET, ssize - 1);
UNSAFE.putObjectVolatile(this, SEGMENTS_OFFSET, oisSegments);
// set hashMask // set hashMask
UNSAFE.putIntVolatile(this, HASHSEED_OFFSET, UNSAFE.putIntVolatile(this, HASHSEED_OFFSET,
@ -1517,6 +1534,9 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
private static final long TBASE; private static final long TBASE;
private static final int TSHIFT; private static final int TSHIFT;
private static final long HASHSEED_OFFSET; private static final long HASHSEED_OFFSET;
private static final long SEGSHIFT_OFFSET;
private static final long SEGMASK_OFFSET;
private static final long SEGMENTS_OFFSET;
static { static {
int ss, ts; int ss, ts;
@ -1530,6 +1550,12 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
ss = UNSAFE.arrayIndexScale(sc); ss = UNSAFE.arrayIndexScale(sc);
HASHSEED_OFFSET = UNSAFE.objectFieldOffset( HASHSEED_OFFSET = UNSAFE.objectFieldOffset(
ConcurrentHashMap.class.getDeclaredField("hashSeed")); ConcurrentHashMap.class.getDeclaredField("hashSeed"));
SEGSHIFT_OFFSET = UNSAFE.objectFieldOffset(
ConcurrentHashMap.class.getDeclaredField("segmentShift"));
SEGMASK_OFFSET = UNSAFE.objectFieldOffset(
ConcurrentHashMap.class.getDeclaredField("segmentMask"));
SEGMENTS_OFFSET = UNSAFE.objectFieldOffset(
ConcurrentHashMap.class.getDeclaredField("segments"));
} catch (Exception e) { } catch (Exception e) {
throw new Error(e); throw new Error(e);
} }

View File

@ -38,7 +38,7 @@ import java.util.Map;
/** /**
* A {@link java.util.Map} providing additional atomic * A {@link java.util.Map} providing additional atomic
* <tt>putIfAbsent</tt>, <tt>remove</tt>, and <tt>replace</tt> methods. * {@code putIfAbsent}, {@code remove}, and {@code replace} methods.
* *
* <p>Memory consistency effects: As with other concurrent * <p>Memory consistency effects: As with other concurrent
* collections, actions in a thread prior to placing an object into a * collections, actions in a thread prior to placing an object into a
@ -57,6 +57,21 @@ import java.util.Map;
* @param <V> the type of mapped values * @param <V> the type of mapped values
*/ */
public interface ConcurrentMap<K, V> extends Map<K, V> { public interface ConcurrentMap<K, V> extends Map<K, V> {
/**
* {@inheritDoc}
*
* @implNote This implementation assumes that the ConcurrentMap cannot
* contain null values and get() returning null unambiguously means the key
* is absent. Implementations which support null values must override this
* default implementation.
*/
@Override
default V getOrDefault(Object key, V defaultValue) {
V v;
return ((v = get(key)) != null) ? v : defaultValue;
}
/** /**
* If the specified key is not already associated * If the specified key is not already associated
* with a value, associate it with the given value. * with a value, associate it with the given value.
@ -91,7 +106,7 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
* Removes the entry for a key only if currently mapped to a given value. * Removes the entry for a key only if currently mapped to a given value.
* This is equivalent to * This is equivalent to
* <pre> {@code * <pre> {@code
* if (map.containsKey(key) && map.get(key).equals(value)) { * if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
* map.remove(key); * map.remove(key);
* return true; * return true;
* } else * } else
@ -101,8 +116,8 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
* *
* @param key key with which the specified value is associated * @param key key with which the specified value is associated
* @param value value expected to be associated with the specified key * @param value value expected to be associated with the specified key
* @return <tt>true</tt> if the value was removed * @return {@code true} if the value was removed
* @throws UnsupportedOperationException if the <tt>remove</tt> operation * @throws UnsupportedOperationException if the {@code remove} operation
* is not supported by this map * is not supported by this map
* @throws ClassCastException if the key or value is of an inappropriate * @throws ClassCastException if the key or value is of an inappropriate
* type for this map * type for this map
@ -117,7 +132,7 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
* Replaces the entry for a key only if currently mapped to a given value. * Replaces the entry for a key only if currently mapped to a given value.
* This is equivalent to * This is equivalent to
* <pre> {@code * <pre> {@code
* if (map.containsKey(key) && map.get(key).equals(oldValue)) { * if (map.containsKey(key) && Objects.equals(map.get(key), oldValue)) {
* map.put(key, newValue); * map.put(key, newValue);
* return true; * return true;
* } else * } else
@ -128,8 +143,8 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
* @param key key with which the specified value is associated * @param key key with which the specified value is associated
* @param oldValue value expected to be associated with the specified key * @param oldValue value expected to be associated with the specified key
* @param newValue value to be associated with the specified key * @param newValue value to be associated with the specified key
* @return <tt>true</tt> if the value was replaced * @return {@code true} if the value was replaced
* @throws UnsupportedOperationException if the <tt>put</tt> operation * @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map * is not supported by this map
* @throws ClassCastException if the class of a specified key or value * @throws ClassCastException if the class of a specified key or value
* prevents it from being stored in this map * prevents it from being stored in this map
@ -154,11 +169,11 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
* @param key key with which the specified value is associated * @param key key with which the specified value is associated
* @param value value to be associated with the specified key * @param value value to be associated with the specified key
* @return the previous value associated with the specified key, or * @return the previous value associated with the specified key, or
* <tt>null</tt> if there was no mapping for the key. * {@code null} if there was no mapping for the key.
* (A <tt>null</tt> return can also indicate that the map * (A {@code null} return can also indicate that the map
* previously associated <tt>null</tt> with the key, * previously associated {@code null} with the key,
* if the implementation supports null values.) * if the implementation supports null values.)
* @throws UnsupportedOperationException if the <tt>put</tt> operation * @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map * is not supported by this map
* @throws ClassCastException if the class of the specified key or value * @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map * prevents it from being stored in this map

View File

@ -37,6 +37,9 @@ package java.util.concurrent.atomic;
import java.util.function.IntUnaryOperator; import java.util.function.IntUnaryOperator;
import java.util.function.IntBinaryOperator; import java.util.function.IntBinaryOperator;
import sun.misc.Unsafe; import sun.misc.Unsafe;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.security.AccessController; import java.security.AccessController;
@ -77,8 +80,9 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* or the field is inaccessible to the caller according to Java language * or the field is inaccessible to the caller according to Java language
* access control * access control
*/ */
@CallerSensitive
public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) { public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName); return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName, Reflection.getCallerClass());
} }
/** /**
@ -365,9 +369,11 @@ public abstract class AtomicIntegerFieldUpdater<T> {
private final Class<T> tclass; private final Class<T> tclass;
private final Class<?> cclass; private final Class<?> cclass;
AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName) { AtomicIntegerFieldUpdaterImpl(final Class<T> tclass,
final String fieldName,
final Class<?> caller)
{
final Field field; final Field field;
final Class<?> caller;
final int modifiers; final int modifiers;
try { try {
field = AccessController.doPrivileged( field = AccessController.doPrivileged(
@ -376,7 +382,6 @@ public abstract class AtomicIntegerFieldUpdater<T> {
return tclass.getDeclaredField(fieldName); return tclass.getDeclaredField(fieldName);
} }
}); });
caller = sun.reflect.Reflection.getCallerClass(3);
modifiers = field.getModifiers(); modifiers = field.getModifiers();
sun.reflect.misc.ReflectUtil.ensureMemberAccess( sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers); caller, tclass, null, modifiers);

View File

@ -37,6 +37,9 @@ package java.util.concurrent.atomic;
import java.util.function.LongUnaryOperator; import java.util.function.LongUnaryOperator;
import java.util.function.LongBinaryOperator; import java.util.function.LongBinaryOperator;
import sun.misc.Unsafe; import sun.misc.Unsafe;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.security.AccessController; import java.security.AccessController;
@ -77,11 +80,13 @@ public abstract class AtomicLongFieldUpdater<T> {
* or the field is inaccessible to the caller according to Java language * or the field is inaccessible to the caller according to Java language
* access control * access control
*/ */
@CallerSensitive
public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) { public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
Class<?> caller = Reflection.getCallerClass();
if (AtomicLong.VM_SUPPORTS_LONG_CAS) if (AtomicLong.VM_SUPPORTS_LONG_CAS)
return new CASUpdater<U>(tclass, fieldName); return new CASUpdater<U>(tclass, fieldName, caller);
else else
return new LockedUpdater<U>(tclass, fieldName); return new LockedUpdater<U>(tclass, fieldName, caller);
} }
/** /**
@ -365,9 +370,8 @@ public abstract class AtomicLongFieldUpdater<T> {
private final Class<T> tclass; private final Class<T> tclass;
private final Class<?> cclass; private final Class<?> cclass;
CASUpdater(final Class<T> tclass, final String fieldName) { CASUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller) {
final Field field; final Field field;
final Class<?> caller;
final int modifiers; final int modifiers;
try { try {
field = AccessController.doPrivileged( field = AccessController.doPrivileged(
@ -376,7 +380,6 @@ public abstract class AtomicLongFieldUpdater<T> {
return tclass.getDeclaredField(fieldName); return tclass.getDeclaredField(fieldName);
} }
}); });
caller = sun.reflect.Reflection.getCallerClass(3);
modifiers = field.getModifiers(); modifiers = field.getModifiers();
sun.reflect.misc.ReflectUtil.ensureMemberAccess( sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers); caller, tclass, null, modifiers);
@ -490,9 +493,8 @@ public abstract class AtomicLongFieldUpdater<T> {
private final Class<T> tclass; private final Class<T> tclass;
private final Class<?> cclass; private final Class<?> cclass;
LockedUpdater(final Class<T> tclass, final String fieldName) { LockedUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller) {
Field field = null; Field field = null;
Class<?> caller = null;
int modifiers = 0; int modifiers = 0;
try { try {
field = AccessController.doPrivileged( field = AccessController.doPrivileged(
@ -501,7 +503,6 @@ public abstract class AtomicLongFieldUpdater<T> {
return tclass.getDeclaredField(fieldName); return tclass.getDeclaredField(fieldName);
} }
}); });
caller = sun.reflect.Reflection.getCallerClass(3);
modifiers = field.getModifiers(); modifiers = field.getModifiers();
sun.reflect.misc.ReflectUtil.ensureMemberAccess( sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers); caller, tclass, null, modifiers);

View File

@ -37,6 +37,9 @@ package java.util.concurrent.atomic;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import java.util.function.BinaryOperator; import java.util.function.BinaryOperator;
import sun.misc.Unsafe; import sun.misc.Unsafe;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.security.AccessController; import java.security.AccessController;
@ -96,10 +99,12 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
* or the field is inaccessible to the caller according to Java language * or the field is inaccessible to the caller according to Java language
* access control * access control
*/ */
@CallerSensitive
public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) { public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) {
return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass, return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass,
vclass, vclass,
fieldName); fieldName,
Reflection.getCallerClass());
} }
/** /**
@ -297,10 +302,11 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
AtomicReferenceFieldUpdaterImpl(final Class<T> tclass, AtomicReferenceFieldUpdaterImpl(final Class<T> tclass,
Class<V> vclass, Class<V> vclass,
final String fieldName) { final String fieldName,
final Class<?> caller)
{
final Field field; final Field field;
final Class<?> fieldClass; final Class<?> fieldClass;
final Class<?> caller;
final int modifiers; final int modifiers;
try { try {
field = AccessController.doPrivileged( field = AccessController.doPrivileged(
@ -309,7 +315,6 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
return tclass.getDeclaredField(fieldName); return tclass.getDeclaredField(fieldName);
} }
}); });
caller = sun.reflect.Reflection.getCallerClass(3);
modifiers = field.getModifiers(); modifiers = field.getModifiers();
sun.reflect.misc.ReflectUtil.ensureMemberAccess( sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers); caller, tclass, null, modifiers);

View File

@ -36,6 +36,8 @@ import java.util.MissingResourceException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Supplier; import java.util.function.Supplier;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
/** /**
* A Logger object is used to log messages for a specific * A Logger object is used to log messages for a specific
@ -333,13 +335,10 @@ public class Logger {
} }
} }
private static Logger demandLogger(String name, String resourceBundleName) { private static Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
LogManager manager = LogManager.getLogManager(); LogManager manager = LogManager.getLogManager();
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null && !SystemLoggerHelper.disableCallerCheck) { if (sm != null && !SystemLoggerHelper.disableCallerCheck) {
// 0: Reflection 1: Logger.demandLogger 2: Logger.getLogger 3: caller
final int SKIP_FRAMES = 3;
Class<?> caller = sun.reflect.Reflection.getCallerClass(SKIP_FRAMES);
if (caller.getClassLoader() == null) { if (caller.getClassLoader() == null) {
return manager.demandSystemLogger(name, resourceBundleName); return manager.demandSystemLogger(name, resourceBundleName);
} }
@ -377,6 +376,7 @@ public class Logger {
// Synchronization is not required here. All synchronization for // Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by LogManager.addLogger(). // adding a new Logger object is handled by LogManager.addLogger().
@CallerSensitive
public static Logger getLogger(String name) { public static Logger getLogger(String name) {
// This method is intentionally not a wrapper around a call // This method is intentionally not a wrapper around a call
// to getLogger(name, resourceBundleName). If it were then // to getLogger(name, resourceBundleName). If it were then
@ -388,7 +388,7 @@ public class Logger {
// would throw an IllegalArgumentException in the second call // would throw an IllegalArgumentException in the second call
// because the wrapper would result in an attempt to replace // because the wrapper would result in an attempt to replace
// the existing "resourceBundleForFoo" with null. // the existing "resourceBundleForFoo" with null.
return demandLogger(name, null); return demandLogger(name, null, Reflection.getCallerClass());
} }
/** /**
@ -434,8 +434,9 @@ public class Logger {
// Synchronization is not required here. All synchronization for // Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by LogManager.addLogger(). // adding a new Logger object is handled by LogManager.addLogger().
@CallerSensitive
public static Logger getLogger(String name, String resourceBundleName) { public static Logger getLogger(String name, String resourceBundleName) {
Logger result = demandLogger(name, resourceBundleName); Logger result = demandLogger(name, resourceBundleName, Reflection.getCallerClass());
// MissingResourceException or IllegalArgumentException can be // MissingResourceException or IllegalArgumentException can be
// thrown by setupResourceInfo(). // thrown by setupResourceInfo().

View File

@ -28,6 +28,7 @@ import java.util.*;
import java.security.*; import java.security.*;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.ServiceConfigurationError; import java.util.ServiceConfigurationError;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
@ -60,9 +61,10 @@ public class ScriptEngineManager {
* *
* @see java.lang.Thread#getContextClassLoader * @see java.lang.Thread#getContextClassLoader
*/ */
@CallerSensitive
public ScriptEngineManager() { public ScriptEngineManager() {
ClassLoader ctxtLoader = Thread.currentThread().getContextClassLoader(); ClassLoader ctxtLoader = Thread.currentThread().getContextClassLoader();
if (canCallerAccessLoader(ctxtLoader)) { if (canCallerAccessLoader(ctxtLoader, Reflection.getCallerClass())) {
if (DEBUG) System.out.println("using " + ctxtLoader); if (DEBUG) System.out.println("using " + ctxtLoader);
init(ctxtLoader); init(ctxtLoader);
} else { } else {
@ -419,10 +421,10 @@ public class ScriptEngineManager {
/** Global bindings associated with script engines created by this manager. */ /** Global bindings associated with script engines created by this manager. */
private Bindings globalScope; private Bindings globalScope;
private boolean canCallerAccessLoader(ClassLoader loader) { private boolean canCallerAccessLoader(ClassLoader loader, Class<?> caller) {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
ClassLoader callerLoader = getCallerClassLoader(); ClassLoader callerLoader = getClassLoader(caller);
if (!sun.misc.VM.isSystemDomainLoader(callerLoader)) { if (!sun.misc.VM.isSystemDomainLoader(callerLoader)) {
if (loader != callerLoader || !isAncestor(loader, callerLoader)) { if (loader != callerLoader || !isAncestor(loader, callerLoader)) {
try { try {
@ -438,10 +440,9 @@ public class ScriptEngineManager {
return true; return true;
} }
// Note that this code is same as ClassLoader.getCallerClassLoader(). // Note that this code is same as ClassLoader.getClassLoader().
// But, that method is package private and hence we can't call here. // But, that method is package private and hence we can't call here.
private ClassLoader getCallerClassLoader() { private ClassLoader getClassLoader(Class<?> caller) {
Class<?> caller = Reflection.getCallerClass(3);
if (caller == null) { if (caller == null) {
return null; return null;
} }

View File

@ -539,7 +539,7 @@ public abstract class EmbeddedFrame extends Frame
public void toBack() {} public void toBack() {}
public void updateFocusableWindowState() {} public void updateFocusableWindowState() {}
public void updateAlwaysOnTop() {} public void updateAlwaysOnTop() {}
public void setAlwaysOnTop(boolean alwaysOnTop) {} public void updateAlwaysOnTopState() {}
public Component getGlobalHeavyweightFocusOwner() { return null; } public Component getGlobalHeavyweightFocusOwner() { return null; }
public void setBoundsPrivate(int x, int y, int width, int height) { public void setBoundsPrivate(int x, int y, int width, int height) {
setBounds(x, y, width, height, SET_BOUNDS); setBounds(x, y, width, height, SET_BOUNDS);

View File

@ -102,11 +102,11 @@ public class TransferableProxy implements Transferable {
protected final boolean isLocal; protected final boolean isLocal;
} }
class ClassLoaderObjectOutputStream extends ObjectOutputStream { final class ClassLoaderObjectOutputStream extends ObjectOutputStream {
private final Map<Set<String>, ClassLoader> map = private final Map<Set<String>, ClassLoader> map =
new HashMap<Set<String>, ClassLoader>(); new HashMap<Set<String>, ClassLoader>();
public ClassLoaderObjectOutputStream(OutputStream os) throws IOException { ClassLoaderObjectOutputStream(OutputStream os) throws IOException {
super(os); super(os);
} }
@ -140,15 +140,15 @@ class ClassLoaderObjectOutputStream extends ObjectOutputStream {
map.put(s, classLoader); map.put(s, classLoader);
} }
public Map<Set<String>, ClassLoader> getClassLoaderMap() { Map<Set<String>, ClassLoader> getClassLoaderMap() {
return new HashMap(map); return new HashMap(map);
} }
} }
class ClassLoaderObjectInputStream extends ObjectInputStream { final class ClassLoaderObjectInputStream extends ObjectInputStream {
private final Map<Set<String>, ClassLoader> map; private final Map<Set<String>, ClassLoader> map;
public ClassLoaderObjectInputStream(InputStream is, ClassLoaderObjectInputStream(InputStream is,
Map<Set<String>, ClassLoader> map) Map<Set<String>, ClassLoader> map)
throws IOException { throws IOException {
super(is); super(is);
@ -166,8 +166,11 @@ class ClassLoaderObjectInputStream extends ObjectInputStream {
s.add(className); s.add(className);
ClassLoader classLoader = map.get(s); ClassLoader classLoader = map.get(s);
if (classLoader != null) {
return Class.forName(className, false, classLoader); return Class.forName(className, false, classLoader);
} else {
return super.resolveClass(classDesc);
}
} }
protected Class<?> resolveProxyClass(String[] interfaces) protected Class<?> resolveProxyClass(String[] interfaces)
@ -179,6 +182,9 @@ class ClassLoaderObjectInputStream extends ObjectInputStream {
} }
ClassLoader classLoader = map.get(s); ClassLoader classLoader = map.get(s);
if (classLoader == null) {
return super.resolveProxyClass(interfaces);
}
// The code below is mostly copied from the superclass. // The code below is mostly copied from the superclass.
ClassLoader nonPublicLoader = null; ClassLoader nonPublicLoader = null;

View File

@ -868,6 +868,15 @@ public class ByteComponentRaster extends SunWritableRaster {
* or if data buffer has not enough capacity. * or if data buffer has not enough capacity.
*/ */
protected final void verify() { protected final void verify() {
/* Need to re-verify the dimensions since a sample model may be
* specified to the constructor
*/
if (width <= 0 || height <= 0 ||
height > (Integer.MAX_VALUE / width))
{
throw new RasterFormatException("Invalid raster dimension");
}
for (int i = 0; i < dataOffsets.length; i++) { for (int i = 0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) { if (dataOffsets[i] < 0) {
throw new RasterFormatException("Data offsets for band " + i throw new RasterFormatException("Data offsets for band " + i
@ -905,13 +914,14 @@ public class ByteComponentRaster extends SunWritableRaster {
lastPixelOffset += lastScanOffset; lastPixelOffset += lastScanOffset;
for (int i = 0; i < numDataElements; i++) { for (int i = 0; i < numDataElements; i++) {
size = lastPixelOffset + dataOffsets[i];
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) { if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
throw new RasterFormatException("Incorrect band offset: " throw new RasterFormatException("Incorrect band offset: "
+ dataOffsets[i]); + dataOffsets[i]);
} }
size = lastPixelOffset + dataOffsets[i];
if (size > maxSize) { if (size > maxSize) {
maxSize = size; maxSize = size;
} }

View File

@ -1368,11 +1368,35 @@ public class BytePackedRaster extends SunWritableRaster {
throw new RasterFormatException("Data offsets must be >= 0"); throw new RasterFormatException("Data offsets must be >= 0");
} }
/* Need to re-verify the dimensions since a sample model may be
* specified to the constructor
*/
if (width <= 0 || height <= 0 ||
height > (Integer.MAX_VALUE / width))
{
throw new RasterFormatException("Invalid raster dimension");
}
/*
* pixelBitstride was verified in constructor, so just make
* sure that it is safe to multiply it by width.
*/
if ((width - 1) > Integer.MAX_VALUE / pixelBitStride) {
throw new RasterFormatException("Invalid raster dimension");
}
if (scanlineStride < 0 ||
scanlineStride > (Integer.MAX_VALUE / height))
{
throw new RasterFormatException("Invalid scanline stride");
}
int lastbit = (dataBitOffset int lastbit = (dataBitOffset
+ (height-1) * scanlineStride * 8 + (height-1) * scanlineStride * 8
+ (width-1) * pixelBitStride + (width-1) * pixelBitStride
+ pixelBitStride - 1); + pixelBitStride - 1);
if (lastbit / 8 >= data.length) { if (lastbit < 0 || lastbit / 8 >= data.length) {
throw new RasterFormatException("raster dimensions overflow " + throw new RasterFormatException("raster dimensions overflow " +
"array bounds"); "array bounds");
} }

View File

@ -333,10 +333,10 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
hints = h; hints = h;
} }
private native void setICMpixels(int x, int y, int w, int h, int[] lut, private native boolean setICMpixels(int x, int y, int w, int h, int[] lut,
byte[] pix, int off, int scansize, byte[] pix, int off, int scansize,
IntegerComponentRaster ict); IntegerComponentRaster ict);
private native int setDiffICM(int x, int y, int w, int h, int[] lut, private native boolean setDiffICM(int x, int y, int w, int h, int[] lut,
int transPix, int numLut, IndexColorModel icm, int transPix, int numLut, IndexColorModel icm,
byte[] pix, int off, int scansize, byte[] pix, int off, int scansize,
ByteComponentRaster bct, int chanOff); ByteComponentRaster bct, int chanOff);
@ -426,10 +426,10 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
IndexColorModel icm = (IndexColorModel) model; IndexColorModel icm = (IndexColorModel) model;
ByteComponentRaster bct = (ByteComponentRaster) biRaster; ByteComponentRaster bct = (ByteComponentRaster) biRaster;
int numlut = numSrcLUT; int numlut = numSrcLUT;
if (setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex, if (!setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex,
numSrcLUT, icm, numSrcLUT, icm,
pix, off, scansize, bct, pix, off, scansize, bct,
bct.getDataOffset(0)) == 0) { bct.getDataOffset(0))) {
convertToRGB(); convertToRGB();
} }
else { else {
@ -470,9 +470,14 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
if (s_useNative) { if (s_useNative) {
// Note that setICMpixels modifies the raster directly // Note that setICMpixels modifies the raster directly
// so we must mark it as changed afterwards // so we must mark it as changed afterwards
setICMpixels(x, y, w, h, srcLUT, pix, off, scansize, if (setICMpixels(x, y, w, h, srcLUT, pix, off, scansize,
iraster); iraster))
{
iraster.markDirty(); iraster.markDirty();
} else {
abort();
return;
}
} }
else { else {
int[] storage = new int[w*h]; int[] storage = new int[w*h];

View File

@ -208,7 +208,7 @@ public class IntegerComponentRaster extends SunWritableRaster {
" SinglePixelPackedSampleModel"); " SinglePixelPackedSampleModel");
} }
verify(false); verify();
} }
@ -629,16 +629,26 @@ public class IntegerComponentRaster extends SunWritableRaster {
} }
/** /**
* Verify that the layout parameters are consistent with * Verify that the layout parameters are consistent with the data.
* the data. If strictCheck *
* is false, this method will check for ArrayIndexOutOfBounds conditions. If * The method verifies whether scanline stride and pixel stride do not
* strictCheck is true, this method will check for additional error * cause an integer overflow during calculation of a position of the pixel
* conditions such as line wraparound (width of a line greater than * in data buffer. It also verifies whether the data buffer has enough data
* the scanline stride). * to correspond the raster layout attributes.
* @return String Error string, if the layout is incompatible with *
* the data. Otherwise returns null. * @throws RasterFormatException if an integer overflow is detected,
* or if data buffer has not enough capacity.
*/ */
private void verify (boolean strictCheck) { protected final void verify() {
/* Need to re-verify the dimensions since a sample model may be
* specified to the constructor
*/
if (width <= 0 || height <= 0 ||
height > (Integer.MAX_VALUE / width))
{
throw new RasterFormatException("Invalid raster dimension");
}
if (dataOffsets[0] < 0) { if (dataOffsets[0] < 0) {
throw new RasterFormatException("Data offset ("+dataOffsets[0]+ throw new RasterFormatException("Data offset ("+dataOffsets[0]+
") must be >= 0"); ") must be >= 0");
@ -647,17 +657,46 @@ public class IntegerComponentRaster extends SunWritableRaster {
int maxSize = 0; int maxSize = 0;
int size; int size;
// we can be sure that width and height are greater than 0
if (scanlineStride < 0 ||
scanlineStride > (Integer.MAX_VALUE / height))
{
// integer overflow
throw new RasterFormatException("Incorrect scanline stride: "
+ scanlineStride);
}
int lastScanOffset = (height - 1) * scanlineStride;
if (pixelStride < 0 ||
pixelStride > (Integer.MAX_VALUE / width))
{
// integer overflow
throw new RasterFormatException("Incorrect pixel stride: "
+ pixelStride);
}
int lastPixelOffset = (width - 1) * pixelStride;
if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
// integer overflow
throw new RasterFormatException("Incorrect raster attributes");
}
lastPixelOffset += lastScanOffset;
for (int i = 0; i < numDataElements; i++) { for (int i = 0; i < numDataElements; i++) {
size = (height-1)*scanlineStride + (width-1)*pixelStride + if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
dataOffsets[i]; throw new RasterFormatException("Incorrect band offset: "
+ dataOffsets[i]);
}
size = lastPixelOffset + dataOffsets[i];
if (size > maxSize) { if (size > maxSize) {
maxSize = size; maxSize = size;
} }
} }
if (data.length < maxSize) { if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+ throw new RasterFormatException("Data array too small (should be "
maxSize + maxSize + " )");
+" but is "+data.length+" )");
} }
} }

View File

@ -151,7 +151,7 @@ public class IntegerInterleavedRaster extends IntegerComponentRaster {
throw new RasterFormatException("IntegerInterleavedRasters must have"+ throw new RasterFormatException("IntegerInterleavedRasters must have"+
" SinglePixelPackedSampleModel"); " SinglePixelPackedSampleModel");
} }
verify(false); verify();
} }
@ -540,31 +540,6 @@ public class IntegerInterleavedRaster extends IntegerComponentRaster {
return createCompatibleWritableRaster(width,height); return createCompatibleWritableRaster(width,height);
} }
/**
* Verify that the layout parameters are consistent with
* the data. If strictCheck
* is false, this method will check for ArrayIndexOutOfBounds conditions. If
* strictCheck is true, this method will check for additional error
* conditions such as line wraparound (width of a line greater than
* the scanline stride).
* @return String Error string, if the layout is incompatible with
* the data. Otherwise returns null.
*/
private void verify (boolean strictCheck) {
int maxSize = 0;
int size;
size = (height-1)*scanlineStride + (width-1) + dataOffsets[0];
if (size > maxSize) {
maxSize = size;
}
if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+
maxSize
+" but is "+data.length+" )");
}
}
public String toString() { public String toString() {
return new String ("IntegerInterleavedRaster: width = "+width return new String ("IntegerInterleavedRaster: width = "+width
+" height = " + height +" height = " + height

View File

@ -802,6 +802,15 @@ public class ShortComponentRaster extends SunWritableRaster {
* or if data buffer has not enough capacity. * or if data buffer has not enough capacity.
*/ */
protected final void verify() { protected final void verify() {
/* Need to re-verify the dimensions since a sample model may be
* specified to the constructor
*/
if (width <= 0 || height <= 0 ||
height > (Integer.MAX_VALUE / width))
{
throw new RasterFormatException("Invalid raster dimension");
}
for (int i = 0; i < dataOffsets.length; i++) { for (int i = 0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) { if (dataOffsets[i] < 0) {
throw new RasterFormatException("Data offsets for band " + i throw new RasterFormatException("Data offsets for band " + i
@ -839,12 +848,13 @@ public class ShortComponentRaster extends SunWritableRaster {
lastPixelOffset += lastScanOffset; lastPixelOffset += lastScanOffset;
for (int i = 0; i < numDataElements; i++) { for (int i = 0; i < numDataElements; i++) {
size = lastPixelOffset + dataOffsets[i];
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) { if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
throw new RasterFormatException("Incorrect band offset: " throw new RasterFormatException("Incorrect band offset: "
+ dataOffsets[i]); + dataOffsets[i]);
} }
size = lastPixelOffset + dataOffsets[i];
if (size > maxSize) { if (size > maxSize) {
maxSize = size; maxSize = size;
} }

View File

@ -841,7 +841,6 @@ abstract class CMap {
CMapFormat6(ByteBuffer bbuffer, int offset, char[] xlat) { CMapFormat6(ByteBuffer bbuffer, int offset, char[] xlat) {
System.err.println("WARNING: CMapFormat8 is untested.");
bbuffer.position(offset+6); bbuffer.position(offset+6);
CharBuffer buffer = bbuffer.asCharBuffer(); CharBuffer buffer = bbuffer.asCharBuffer();
firstCode = buffer.get(); firstCode = buffer.get();
@ -884,7 +883,6 @@ abstract class CMap {
CMapFormat8(ByteBuffer bbuffer, int offset, char[] xlat) { CMapFormat8(ByteBuffer bbuffer, int offset, char[] xlat) {
System.err.println("WARNING: CMapFormat8 is untested.");
bbuffer.position(12); bbuffer.position(12);
bbuffer.get(is32); bbuffer.get(is32);
nGroups = bbuffer.getInt(); nGroups = bbuffer.getInt();
@ -915,7 +913,6 @@ abstract class CMap {
CMapFormat10(ByteBuffer bbuffer, int offset, char[] xlat) { CMapFormat10(ByteBuffer bbuffer, int offset, char[] xlat) {
System.err.println("WARNING: CMapFormat10 is untested.");
firstCode = bbuffer.getInt() & INTMASK; firstCode = bbuffer.getInt() & INTMASK;
entryCount = bbuffer.getInt() & INTMASK; entryCount = bbuffer.getInt() & INTMASK;
bbuffer.position(offset+20); bbuffer.position(offset+20);

View File

@ -85,45 +85,72 @@ class LCMSImageLayout {
private boolean imageAtOnce = false; private boolean imageAtOnce = false;
Object dataArray; Object dataArray;
private LCMSImageLayout(int np, int pixelType, int pixelSize) { private int dataArrayLength; /* in bytes */
private LCMSImageLayout(int np, int pixelType, int pixelSize)
throws ImageLayoutException
{
this.pixelType = pixelType; this.pixelType = pixelType;
width = np; width = np;
height = 1; height = 1;
nextRowOffset = np * pixelSize; nextRowOffset = safeMult(pixelSize, np);
offset = 0; offset = 0;
} }
private LCMSImageLayout(int width, int height, int pixelType, private LCMSImageLayout(int width, int height, int pixelType,
int pixelSize) { int pixelSize)
throws ImageLayoutException
{
this.pixelType = pixelType; this.pixelType = pixelType;
this.width = width; this.width = width;
this.height = height; this.height = height;
nextRowOffset = width * pixelSize; nextRowOffset = safeMult(pixelSize, width);
offset = 0; offset = 0;
} }
public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) {
public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize)
throws ImageLayoutException
{
this(np, pixelType, pixelSize); this(np, pixelType, pixelSize);
dataType = DT_BYTE; dataType = DT_BYTE;
dataArray = data; dataArray = data;
dataArrayLength = data.length;
verify();
} }
public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize) { public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize)
throws ImageLayoutException
{
this(np, pixelType, pixelSize); this(np, pixelType, pixelSize);
dataType = DT_SHORT; dataType = DT_SHORT;
dataArray = data; dataArray = data;
dataArrayLength = 2 * data.length;
verify();
} }
public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize) { public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize)
throws ImageLayoutException
{
this(np, pixelType, pixelSize); this(np, pixelType, pixelSize);
dataType = DT_INT; dataType = DT_INT;
dataArray = data; dataArray = data;
dataArrayLength = 4 * data.length;
verify();
} }
public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize) { public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize)
throws ImageLayoutException
{
this(np, pixelType, pixelSize); this(np, pixelType, pixelSize);
dataType = DT_DOUBLE; dataType = DT_DOUBLE;
dataArray = data; dataArray = data;
dataArrayLength = 8 * data.length;
verify();
} }
private LCMSImageLayout() { private LCMSImageLayout() {
@ -132,7 +159,7 @@ class LCMSImageLayout {
/* This method creates a layout object for given image. /* This method creates a layout object for given image.
* Returns null if the image is not supported by current implementation. * Returns null if the image is not supported by current implementation.
*/ */
public static LCMSImageLayout createImageLayout(BufferedImage image) { public static LCMSImageLayout createImageLayout(BufferedImage image) throws ImageLayoutException {
LCMSImageLayout l = new LCMSImageLayout(); LCMSImageLayout l = new LCMSImageLayout();
switch (image.getType()) { switch (image.getType()) {
@ -193,9 +220,10 @@ class LCMSImageLayout {
do { do {
IntegerComponentRaster intRaster = (IntegerComponentRaster) IntegerComponentRaster intRaster = (IntegerComponentRaster)
image.getRaster(); image.getRaster();
l.nextRowOffset = intRaster.getScanlineStride() * 4; l.nextRowOffset = safeMult(4, intRaster.getScanlineStride());
l.offset = intRaster.getDataOffset(0) * 4; l.offset = safeMult(4, intRaster.getDataOffset(0));
l.dataArray = intRaster.getDataStorage(); l.dataArray = intRaster.getDataStorage();
l.dataArrayLength = 4 * intRaster.getDataStorage().length;
l.dataType = DT_INT; l.dataType = DT_INT;
if (l.nextRowOffset == l.width * 4 * intRaster.getPixelStride()) { if (l.nextRowOffset == l.width * 4 * intRaster.getPixelStride()) {
@ -213,6 +241,7 @@ class LCMSImageLayout {
int firstBand = image.getSampleModel().getNumBands() - 1; int firstBand = image.getSampleModel().getNumBands() - 1;
l.offset = byteRaster.getDataOffset(firstBand); l.offset = byteRaster.getDataOffset(firstBand);
l.dataArray = byteRaster.getDataStorage(); l.dataArray = byteRaster.getDataStorage();
l.dataArrayLength = byteRaster.getDataStorage().length;
l.dataType = DT_BYTE; l.dataType = DT_BYTE;
if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) { if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
l.imageAtOnce = true; l.imageAtOnce = true;
@ -225,6 +254,7 @@ class LCMSImageLayout {
ByteComponentRaster byteRaster = (ByteComponentRaster) ByteComponentRaster byteRaster = (ByteComponentRaster)
image.getRaster(); image.getRaster();
l.nextRowOffset = byteRaster.getScanlineStride(); l.nextRowOffset = byteRaster.getScanlineStride();
l.dataArrayLength = byteRaster.getDataStorage().length;
l.offset = byteRaster.getDataOffset(0); l.offset = byteRaster.getDataOffset(0);
l.dataArray = byteRaster.getDataStorage(); l.dataArray = byteRaster.getDataStorage();
l.dataType = DT_BYTE; l.dataType = DT_BYTE;
@ -239,9 +269,10 @@ class LCMSImageLayout {
do { do {
ShortComponentRaster shortRaster = (ShortComponentRaster) ShortComponentRaster shortRaster = (ShortComponentRaster)
image.getRaster(); image.getRaster();
l.nextRowOffset = shortRaster.getScanlineStride() * 2; l.nextRowOffset = safeMult(2, shortRaster.getScanlineStride());
l.offset = shortRaster.getDataOffset(0) * 2; l.offset = safeMult(2, shortRaster.getDataOffset(0));
l.dataArray = shortRaster.getDataStorage(); l.dataArray = shortRaster.getDataStorage();
l.dataArrayLength = 2 * shortRaster.getDataStorage().length;
l.dataType = DT_SHORT; l.dataType = DT_SHORT;
if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) { if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) {
@ -252,6 +283,7 @@ class LCMSImageLayout {
default: default:
return null; return null;
} }
l.verify();
return l; return l;
} }
@ -293,6 +325,46 @@ class LCMSImageLayout {
} }
} }
private void verify() throws ImageLayoutException {
if (offset < 0 || offset >= dataArrayLength) {
throw new ImageLayoutException("Invalid image layout");
}
int lastPixelOffset = safeMult(nextRowOffset, (height - 1));
lastPixelOffset = safeAdd(lastPixelOffset, (width - 1));
int off = safeAdd(offset, lastPixelOffset);
if (off < 0 || off >= dataArrayLength) {
throw new ImageLayoutException("Invalid image layout");
}
}
static int safeAdd(int a, int b) throws ImageLayoutException {
long res = a;
res += b;
if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
throw new ImageLayoutException("Invalid image layout");
}
return (int)res;
}
static int safeMult(int a, int b) throws ImageLayoutException {
long res = a;
res *= b;
if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
throw new ImageLayoutException("Invalid image layout");
}
return (int)res;
}
public static class ImageLayoutException extends Exception {
public ImageLayoutException(String message) {
super(message);
}
}
public static LCMSImageLayout createImageLayout(Raster r) { public static LCMSImageLayout createImageLayout(Raster r) {
LCMSImageLayout l = new LCMSImageLayout(); LCMSImageLayout l = new LCMSImageLayout();
if (r instanceof ByteComponentRaster) { if (r instanceof ByteComponentRaster) {

View File

@ -51,6 +51,7 @@ import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.ComponentSampleModel; import java.awt.image.ComponentSampleModel;
import sun.java2d.cmm.*; import sun.java2d.cmm.*;
import sun.java2d.cmm.lcms.*; import sun.java2d.cmm.lcms.*;
import static sun.java2d.cmm.lcms.LCMSImageLayout.ImageLayoutException;
public class LCMSTransform implements ColorTransform { public class LCMSTransform implements ColorTransform {
@ -162,6 +163,7 @@ public class LCMSTransform implements ColorTransform {
public void colorConvert(BufferedImage src, BufferedImage dst) { public void colorConvert(BufferedImage src, BufferedImage dst) {
LCMSImageLayout srcIL, dstIL; LCMSImageLayout srcIL, dstIL;
try {
dstIL = LCMSImageLayout.createImageLayout(dst); dstIL = LCMSImageLayout.createImageLayout(dst);
@ -172,6 +174,9 @@ public class LCMSTransform implements ColorTransform {
return; return;
} }
} }
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert images");
}
Raster srcRas = src.getRaster(); Raster srcRas = src.getRaster();
WritableRaster dstRas = dst.getRaster(); WritableRaster dstRas = dst.getRaster();
@ -228,6 +233,7 @@ public class LCMSTransform implements ColorTransform {
} }
int idx; int idx;
// TODO check for src npixels = dst npixels // TODO check for src npixels = dst npixels
try {
srcIL = new LCMSImageLayout( srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(), srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
@ -236,6 +242,9 @@ public class LCMSTransform implements ColorTransform {
dstLine, dstLine.length/getNumOutComponents(), dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumOutComponents()); LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert images");
}
// process each scanline // process each scanline
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
// convert src scanline // convert src scanline
@ -284,6 +293,7 @@ public class LCMSTransform implements ColorTransform {
alpha = new float[w]; alpha = new float[w];
} }
int idx; int idx;
try {
srcIL = new LCMSImageLayout( srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(), srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
@ -293,7 +303,9 @@ public class LCMSTransform implements ColorTransform {
dstLine, dstLine.length/getNumOutComponents(), dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert images");
}
// process each scanline // process each scanline
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
// convert src scanline // convert src scanline
@ -402,6 +414,7 @@ public class LCMSTransform implements ColorTransform {
short[] srcLine = new short[w * srcNumBands]; short[] srcLine = new short[w * srcNumBands];
short[] dstLine = new short[w * dstNumBands]; short[] dstLine = new short[w * dstNumBands];
int idx; int idx;
try {
srcIL = new LCMSImageLayout( srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(), srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
@ -411,7 +424,9 @@ public class LCMSTransform implements ColorTransform {
dstLine, dstLine.length/getNumOutComponents(), dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert rasters");
}
// process each scanline // process each scanline
for (int y = 0; y < h; y++, ys++, yd++) { for (int y = 0; y < h; y++, ys++, yd++) {
// get src scanline // get src scanline
@ -502,6 +517,7 @@ public class LCMSTransform implements ColorTransform {
byte[] dstLine = new byte[w * dstNumBands]; byte[] dstLine = new byte[w * dstNumBands];
int idx; int idx;
// TODO check for src npixels = dst npixels // TODO check for src npixels = dst npixels
try {
srcIL = new LCMSImageLayout( srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(), srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
@ -510,7 +526,9 @@ public class LCMSTransform implements ColorTransform {
dstLine, dstLine.length/getNumOutComponents(), dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumOutComponents()); LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert rasters");
}
// process each scanline // process each scanline
for (int y = 0; y < h; y++, ys++, yd++) { for (int y = 0; y < h; y++, ys++, yd++) {
// get src scanline // get src scanline
@ -542,6 +560,8 @@ public class LCMSTransform implements ColorTransform {
short[] srcLine = new short[w * srcNumBands]; short[] srcLine = new short[w * srcNumBands];
short[] dstLine = new short[w * dstNumBands]; short[] dstLine = new short[w * dstNumBands];
int idx; int idx;
try {
srcIL = new LCMSImageLayout( srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(), srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
@ -551,7 +571,9 @@ public class LCMSTransform implements ColorTransform {
dstLine, dstLine.length/getNumOutComponents(), dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert rasters");
}
// process each scanline // process each scanline
for (int y = 0; y < h; y++, ys++, yd++) { for (int y = 0; y < h; y++, ys++, yd++) {
// get src scanline // get src scanline
@ -592,6 +614,7 @@ public class LCMSTransform implements ColorTransform {
dst = new short [(src.length/getNumInComponents())*getNumOutComponents()]; dst = new short [(src.length/getNumInComponents())*getNumOutComponents()];
} }
try {
LCMSImageLayout srcIL = new LCMSImageLayout( LCMSImageLayout srcIL = new LCMSImageLayout(
src, src.length/getNumInComponents(), src, src.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
@ -605,6 +628,9 @@ public class LCMSTransform implements ColorTransform {
doTransform(srcIL, dstIL); doTransform(srcIL, dstIL);
return dst; return dst;
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert data");
}
} }
public byte[] colorConvert(byte[] src, byte[] dst) { public byte[] colorConvert(byte[] src, byte[] dst) {
@ -612,6 +638,7 @@ public class LCMSTransform implements ColorTransform {
dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()]; dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()];
} }
try {
LCMSImageLayout srcIL = new LCMSImageLayout( LCMSImageLayout srcIL = new LCMSImageLayout(
src, src.length/getNumInComponents(), src, src.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
@ -625,5 +652,8 @@ public class LCMSTransform implements ColorTransform {
doTransform(srcIL, dstIL); doTransform(srcIL, dstIL);
return dst; return dst;
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert data");
}
} }
} }

View File

@ -28,6 +28,9 @@ package sun.misc;
import java.security.*; import java.security.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
/** /**
* A collection of methods for performing low-level, unsafe operations. * A collection of methods for performing low-level, unsafe operations.
@ -80,9 +83,10 @@ public final class Unsafe {
* <code>checkPropertiesAccess</code> method doesn't allow * <code>checkPropertiesAccess</code> method doesn't allow
* access to the system properties. * access to the system properties.
*/ */
@CallerSensitive
public static Unsafe getUnsafe() { public static Unsafe getUnsafe() {
Class<?> cc = sun.reflect.Reflection.getCallerClass(2); Class<?> caller = Reflection.getCallerClass();
if (!VM.isSystemDomainLoader(cc.getClassLoader())) if (!VM.isSystemDomainLoader(caller.getClassLoader()))
throw new SecurityException("Unsafe"); throw new SecurityException("Unsafe");
return theUnsafe; return theUnsafe;
} }
@ -817,8 +821,6 @@ public final class Unsafe {
ClassLoader loader, ClassLoader loader,
ProtectionDomain protectionDomain); ProtectionDomain protectionDomain);
public native Class<?> defineClass(String name, byte[] b, int off, int len);
/** /**
* Define a class but do not make it known to the class loader or system dictionary. * Define a class but do not make it known to the class loader or system dictionary.
* <p> * <p>

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2013, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
/**
* A method annotated @CallerSensitive is sensitive to its calling class,
* via {@link sun.reflect.Reflection#getCallerClass Reflection.getCallerClass},
* or via some equivalent.
*
* @author John R. Rose
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({CONSTRUCTOR, METHOD})
public @interface CallerSensitive {
}

View File

@ -51,16 +51,11 @@ public class Reflection {
methodFilterMap = new HashMap<>(); methodFilterMap = new HashMap<>();
} }
/** Returns the class of the method <code>realFramesToSkip</code> /** Returns the class of the caller of the method calling this method,
frames up the stack (zero-based), ignoring frames associated ignoring frames associated with java.lang.reflect.Method.invoke()
with java.lang.reflect.Method.invoke() and its implementation. and its implementation. */
The first frame is that associated with this method, so @CallerSensitive
<code>getCallerClass(0)</code> returns the Class object for public static native Class<?> getCallerClass();
sun.reflect.Reflection. Frames associated with
java.lang.reflect.Method.invoke() and its implementation are
completely ignored and do not count toward the number of "real"
frames skipped. */
public static native Class<?> getCallerClass(int realFramesToSkip);
/** Retrieves the access flags written to the class file. For /** Retrieves the access flags written to the class file. For
inner classes these flags may differ from those returned by inner classes these flags may differ from those returned by
@ -321,4 +316,27 @@ public class Reflection {
} }
return newMembers; return newMembers;
} }
/**
* Tests if the given method is caller-sensitive and the declaring class
* is defined by either the bootstrap class loader or extension class loader.
*/
public static boolean isCallerSensitive(Method m) {
final ClassLoader loader = m.getDeclaringClass().getClassLoader();
if (sun.misc.VM.isSystemDomainLoader(loader) || isExtClassLoader(loader)) {
return m.isAnnotationPresent(CallerSensitive.class);
}
return false;
}
private static boolean isExtClassLoader(ClassLoader loader) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
while (cl != null) {
if (cl.getParent() == null && cl == loader) {
return true;
}
cl = cl.getParent();
}
return false;
}
} }

View File

@ -46,8 +46,28 @@ import sun.misc.IOUtils;
class Trampoline { class Trampoline {
static {
if (Trampoline.class.getClassLoader() == null) {
throw new Error(
"Trampoline must not be defined by the bootstrap classloader");
}
}
private static void ensureInvocableMethod(Method m)
throws InvocationTargetException
{
Class<?> clazz = m.getDeclaringClass();
if (clazz.equals(AccessController.class) ||
clazz.equals(Method.class) ||
clazz.getName().startsWith("java.lang.invoke."))
throw new InvocationTargetException(
new UnsupportedOperationException("invocation not supported"));
}
private static Object invoke(Method m, Object obj, Object[] params) private static Object invoke(Method m, Object obj, Object[] params)
throws InvocationTargetException, IllegalAccessException { throws InvocationTargetException, IllegalAccessException
{
ensureInvocableMethod(m);
return m.invoke(obj, params); return m.invoke(obj, params);
} }
} }
@ -251,16 +271,6 @@ public final class MethodUtil extends SecureClassLoader {
*/ */
public static Object invoke(Method m, Object obj, Object[] params) public static Object invoke(Method m, Object obj, Object[] params)
throws InvocationTargetException, IllegalAccessException { throws InvocationTargetException, IllegalAccessException {
if (m.getDeclaringClass().equals(AccessController.class) ||
(m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.class)
&& m.getName().equals("lookup")) ||
(m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.Lookup.class)
&& (m.getName().startsWith("find") ||
m.getName().startsWith("bind") ||
m.getName().startsWith("unreflect"))) ||
m.getDeclaringClass().equals(Method.class))
throw new InvocationTargetException(
new UnsupportedOperationException("invocation not supported"));
try { try {
return bounce.invoke(null, new Object[] {m, obj, params}); return bounce.invoke(null, new Object[] {m, obj, params});
} catch (InvocationTargetException ie) { } catch (InvocationTargetException ie) {
@ -293,7 +303,7 @@ public final class MethodUtil extends SecureClassLoader {
Method.class, Object.class, Object[].class Method.class, Object.class, Object[].class
}; };
Method b = t.getDeclaredMethod("invoke", types); Method b = t.getDeclaredMethod("invoke", types);
((AccessibleObject)b).setAccessible(true); b.setAccessible(true);
return b; return b;
} }
}); });

View File

@ -55,13 +55,19 @@ import java.rmi.server.RMIClassLoader;
public class MarshalInputStream extends ObjectInputStream { public class MarshalInputStream extends ObjectInputStream {
/** /**
* value of "java.rmi.server.useCodebaseOnly" property, * Value of "java.rmi.server.useCodebaseOnly" property,
* as cached at class initialization time. * as cached at class initialization time.
*
* The default value is true. That is, the value is true
* if the property is absent or is not equal to "false".
* The value is only false when the property is present
* and is equal to "false".
*/ */
private static final boolean useCodebaseOnlyProperty = private static final boolean useCodebaseOnlyProperty =
java.security.AccessController.doPrivileged( ! java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction( new sun.security.action.GetPropertyAction(
"java.rmi.server.useCodebaseOnly")).booleanValue(); "java.rmi.server.useCodebaseOnly", "true"))
.equalsIgnoreCase("false");
/** table to hold sun classes to which access is explicitly permitted */ /** table to hold sun classes to which access is explicitly permitted */
protected static Map<String, Class<?>> permittedSunClasses protected static Map<String, Class<?>> permittedSunClasses

View File

@ -204,7 +204,7 @@ public class KrbApReq {
int usage) int usage)
throws KrbException, IOException { throws KrbException, IOException {
ctime = new KerberosTime(KerberosTime.NOW); ctime = KerberosTime.now();
init(options, init(options,
tgs_creds.ticket, tgs_creds.ticket,
tgs_creds.key, tgs_creds.key,
@ -287,14 +287,14 @@ public class KrbApReq {
authenticator = new Authenticator(temp2); authenticator = new Authenticator(temp2);
ctime = authenticator.ctime; ctime = authenticator.ctime;
cusec = authenticator.cusec; cusec = authenticator.cusec;
authenticator.ctime.setMicroSeconds(authenticator.cusec); authenticator.ctime =
authenticator.ctime.withMicroSeconds(authenticator.cusec);
if (!authenticator.cname.equals(enc_ticketPart.cname)) { if (!authenticator.cname.equals(enc_ticketPart.cname)) {
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADMATCH); throw new KrbApErrException(Krb5.KRB_AP_ERR_BADMATCH);
} }
KerberosTime currTime = new KerberosTime(KerberosTime.NOW); if (!authenticator.ctime.inClockSkew())
if (!authenticator.ctime.inClockSkew(currTime))
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW); throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
// start to check if it is a replay attack. // start to check if it is a replay attack.
@ -304,7 +304,7 @@ public class KrbApReq {
if (table.get(time, authenticator.cname.toString()) != null) { if (table.get(time, authenticator.cname.toString()) != null) {
throw new KrbApErrException(Krb5.KRB_AP_ERR_REPEAT); throw new KrbApErrException(Krb5.KRB_AP_ERR_REPEAT);
} else { } else {
table.put(client, time, currTime.getTime()); table.put(client, time, System.currentTimeMillis());
} }
if (initiator != null) { if (initiator != null) {
@ -329,7 +329,7 @@ public class KrbApReq {
// else // else
// save authenticator to check for later // save authenticator to check for later
KerberosTime now = new KerberosTime(KerberosTime.NOW); KerberosTime now = KerberosTime.now();
if ((enc_ticketPart.starttime != null && if ((enc_ticketPart.starttime != null &&
enc_ticketPart.starttime.greaterThanWRTClockSkew(now)) || enc_ticketPart.starttime.greaterThanWRTClockSkew(now)) ||

View File

@ -71,12 +71,18 @@ abstract class KrbAppMessage {
} }
if (packetTimestamp != null) { if (packetTimestamp != null) {
packetTimestamp.setMicroSeconds(packetUsec); if (packetUsec != null) {
if (!packetTimestamp.inClockSkew()) packetTimestamp =
packetTimestamp.withMicroSeconds(packetUsec.intValue());
}
if (!packetTimestamp.inClockSkew()) {
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW); throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
} else }
if (timestampRequired) } else {
if (timestampRequired) {
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW); throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
}
}
// XXX check replay cache // XXX check replay cache
// if (rcache.repeated(packetTimestamp, packetUsec, packetSAddress)) // if (rcache.repeated(packetTimestamp, packetUsec, packetSAddress))

View File

@ -103,7 +103,7 @@ public class KrbCred {
delegatedCreds.renewTill, tgService, delegatedCreds.renewTill, tgService,
delegatedCreds.cAddr); delegatedCreds.cAddr);
timeStamp = new KerberosTime(KerberosTime.NOW); timeStamp = KerberosTime.now();
KrbCredInfo[] credInfos = {credInfo}; KrbCredInfo[] credInfos = {credInfo};
EncKrbCredPart encPart = EncKrbCredPart encPart =
new EncKrbCredPart(credInfos, new EncKrbCredPart(credInfos,

View File

@ -147,8 +147,7 @@ public class KrbTgsReq {
princName = cname; princName = cname;
servName = sname; servName = sname;
ctime = new KerberosTime(KerberosTime.NOW); ctime = KerberosTime.now();
// check if they are valid arguments. The optional fields // check if they are valid arguments. The optional fields
// should be consistent with settings in KDCOptions. // should be consistent with settings in KDCOptions.

View File

@ -30,18 +30,20 @@
package sun.security.krb5.internal; package sun.security.krb5.internal;
import java.util.TimeZone; import sun.security.krb5.Asn1Exception;
import sun.security.util.*;
import sun.security.krb5.Config; import sun.security.krb5.Config;
import sun.security.krb5.KrbException; import sun.security.krb5.KrbException;
import sun.security.krb5.Asn1Exception; import sun.security.util.DerInputStream;
import java.util.Date; import sun.security.util.DerOutputStream;
import java.util.GregorianCalendar; import sun.security.util.DerValue;
import java.util.Calendar;
import java.io.IOException; import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
/** /**
* Implements the ASN.1 KerberosTime type. * Implements the ASN.1 KerberosTime type. This is an immutable class.
* *
* <xmp> * <xmp>
* KerberosTime ::= GeneralizedTime -- with no fractional seconds * KerberosTime ::= GeneralizedTime -- with no fractional seconds
@ -62,55 +64,38 @@ import java.io.IOException;
* same class can be used as a precise timestamp in Authenticator etc. * same class can be used as a precise timestamp in Authenticator etc.
*/ */
public class KerberosTime implements Cloneable { public class KerberosTime {
private long kerberosTime; // milliseconds since epoch, a Date.getTime() value private final long kerberosTime; // milliseconds since epoch, Date.getTime()
private int microSeconds; // the last three digits of the microsecond value private final int microSeconds; // last 3 digits of the real microsecond
// The time when this class is loaded. Used in setNow() // The time when this class is loaded. Used in setNow()
private static long initMilli = System.currentTimeMillis(); private static long initMilli = System.currentTimeMillis();
private static long initMicro = System.nanoTime() / 1000; private static long initMicro = System.nanoTime() / 1000;
private static long syncTime;
private static boolean DEBUG = Krb5.DEBUG; private static boolean DEBUG = Krb5.DEBUG;
public static final boolean NOW = true; // Do not make this public. It's a little confusing that micro
public static final boolean UNADJUSTED_NOW = false; // is only the last 3 digits of microsecond.
public KerberosTime(long time) {
kerberosTime = time;
}
private KerberosTime(long time, int micro) { private KerberosTime(long time, int micro) {
kerberosTime = time; kerberosTime = time;
microSeconds = micro; microSeconds = micro;
} }
public Object clone() { /**
return new KerberosTime(kerberosTime, microSeconds); * Creates a KerberosTime object from milliseconds since epoch.
*/
public KerberosTime(long time) {
this(time, 0);
} }
// This constructor is used in the native code // This constructor is used in the native code
// src/windows/native/sun/security/krb5/NativeCreds.c // src/windows/native/sun/security/krb5/NativeCreds.c
public KerberosTime(String time) throws Asn1Exception { public KerberosTime(String time) throws Asn1Exception {
kerberosTime = toKerberosTime(time); this(toKerberosTime(time), 0);
}
/**
* Constructs a KerberosTime object.
* @param encoding a DER-encoded data.
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
* @exception IOException if an I/O error occurs while reading encoded data.
*/
public KerberosTime(DerValue encoding) throws Asn1Exception, IOException {
GregorianCalendar calendar = new GregorianCalendar();
Date temp = encoding.getGeneralizedTime();
kerberosTime = temp.getTime();
} }
private static long toKerberosTime(String time) throws Asn1Exception { private static long toKerberosTime(String time) throws Asn1Exception {
// this method only used by KerberosTime class.
// ASN.1 GeneralizedTime format: // ASN.1 GeneralizedTime format:
// "19700101000000Z" // "19700101000000Z"
@ -133,30 +118,34 @@ public class KerberosTime implements Cloneable {
Integer.parseInt(time.substring(8, 10)), Integer.parseInt(time.substring(8, 10)),
Integer.parseInt(time.substring(10, 12)), Integer.parseInt(time.substring(10, 12)),
Integer.parseInt(time.substring(12, 14))); Integer.parseInt(time.substring(12, 14)));
return calendar.getTimeInMillis();
//The Date constructor assumes the setting are local relative
//and converts the time to UTC before storing it. Since we
//want the internal representation to correspond to local
//and not UTC time we subtract the UTC time offset.
return (calendar.getTime().getTime());
}
// should be moved to sun.security.krb5.util class
public static String zeroPad(String s, int length) {
StringBuffer temp = new StringBuffer(s);
while (temp.length() < length)
temp.insert(0, '0');
return temp.toString();
} }
/**
* Creates a KerberosTime object from a Date object.
*/
public KerberosTime(Date time) { public KerberosTime(Date time) {
kerberosTime = time.getTime(); // (time.getTimezoneOffset() * 60000L); this(time.getTime(), 0);
} }
public KerberosTime(boolean initToNow) { /**
if (initToNow) { * Creates a KerberosTime object for now. It uses System.nanoTime()
setNow(); * to get a more precise time than "new Date()".
*/
public static KerberosTime now() {
long newMilli = System.currentTimeMillis();
long newMicro = System.nanoTime() / 1000;
long microElapsed = newMicro - initMicro;
long calcMilli = initMilli + microElapsed/1000;
if (calcMilli - newMilli > 100 || newMilli - calcMilli > 100) {
if (DEBUG) {
System.out.println("System time adjusted");
}
initMilli = newMilli;
initMicro = newMicro;
return new KerberosTime(newMilli, 0);
} else {
return new KerberosTime(calcMilli, (int)(microElapsed % 1000));
} }
} }
@ -169,13 +158,13 @@ public class KerberosTime implements Cloneable {
calendar.clear(); calendar.clear();
calendar.setTimeInMillis(kerberosTime); calendar.setTimeInMillis(kerberosTime);
return zeroPad(Integer.toString(calendar.get(Calendar.YEAR)), 4) + return String.format("%04d%02d%02d%02d%02d%02dZ",
zeroPad(Integer.toString(calendar.get(Calendar.MONTH) + 1), 2) + calendar.get(Calendar.YEAR),
zeroPad(Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)), 2) + calendar.get(Calendar.MONTH) + 1,
zeroPad(Integer.toString(calendar.get(Calendar.HOUR_OF_DAY)), 2) + calendar.get(Calendar.DAY_OF_MONTH),
zeroPad(Integer.toString(calendar.get(Calendar.MINUTE)), 2) + calendar.get(Calendar.HOUR_OF_DAY),
zeroPad(Integer.toString(calendar.get(Calendar.SECOND)), 2) + 'Z'; calendar.get(Calendar.MINUTE),
calendar.get(Calendar.SECOND));
} }
/** /**
@ -194,40 +183,8 @@ public class KerberosTime implements Cloneable {
return kerberosTime; return kerberosTime;
} }
public void setTime(Date time) {
kerberosTime = time.getTime(); // (time.getTimezoneOffset() * 60000L);
microSeconds = 0;
}
public void setTime(long time) {
kerberosTime = time;
microSeconds = 0;
}
public Date toDate() { public Date toDate() {
Date temp = new Date(kerberosTime); return new Date(kerberosTime);
temp.setTime(temp.getTime());
return temp;
}
public void setNow() {
long newMilli = System.currentTimeMillis();
long newMicro = System.nanoTime() / 1000;
long microElapsed = newMicro - initMicro;
long calcMilli = initMilli + microElapsed/1000;
if (calcMilli - newMilli > 100 || newMilli - calcMilli > 100) {
if (DEBUG) {
System.out.println("System time adjusted");
}
initMilli = newMilli;
initMicro = newMicro;
setTime(newMilli);
microSeconds = 0;
} else {
setTime(calcMilli);
microSeconds = (int)(microElapsed % 1000);
}
} }
public int getMicroSeconds() { public int getMicroSeconds() {
@ -235,45 +192,25 @@ public class KerberosTime implements Cloneable {
return temp_long.intValue() + microSeconds; return temp_long.intValue() + microSeconds;
} }
public void setMicroSeconds(int usec) { /**
microSeconds = usec % 1000; * Returns a new KerberosTime object with the original seconds
Integer temp_int = new Integer(usec); * and the given microseconds.
long temp_long = temp_int.longValue() / 1000L; */
kerberosTime = kerberosTime - (kerberosTime % 1000L) + temp_long; public KerberosTime withMicroSeconds(int usec) {
return new KerberosTime(
kerberosTime - kerberosTime%1000L + usec/1000L,
usec%1000);
} }
public void setMicroSeconds(Integer usec) { private boolean inClockSkew(int clockSkew) {
if (usec != null) { return java.lang.Math.abs(kerberosTime - System.currentTimeMillis())
microSeconds = usec.intValue() % 1000; <= clockSkew * 1000L;
long temp_long = usec.longValue() / 1000L;
kerberosTime = kerberosTime - (kerberosTime % 1000L) + temp_long;
}
}
public boolean inClockSkew(int clockSkew) {
KerberosTime now = new KerberosTime(KerberosTime.NOW);
if (java.lang.Math.abs(kerberosTime - now.kerberosTime) >
clockSkew * 1000L)
return false;
return true;
} }
public boolean inClockSkew() { public boolean inClockSkew() {
return inClockSkew(getDefaultSkew()); return inClockSkew(getDefaultSkew());
} }
public boolean inClockSkew(int clockSkew, KerberosTime now) {
if (java.lang.Math.abs(kerberosTime - now.kerberosTime) >
clockSkew * 1000L)
return false;
return true;
}
public boolean inClockSkew(KerberosTime time) {
return inClockSkew(getDefaultSkew(), time);
}
public boolean greaterThanWRTClockSkew(KerberosTime time, int clockSkew) { public boolean greaterThanWRTClockSkew(KerberosTime time, int clockSkew) {
if ((kerberosTime - time.kerberosTime) > clockSkew * 1000L) if ((kerberosTime - time.kerberosTime) > clockSkew * 1000L)
return true; return true;
@ -317,24 +254,22 @@ public class KerberosTime implements Cloneable {
return temp_long.intValue(); return temp_long.intValue();
} }
public void setSeconds(int sec) {
Integer temp_int = new Integer(sec);
kerberosTime = temp_int.longValue() * 1000L;
}
/** /**
* Parse (unmarshal) a kerberostime from a DER input stream. This form * Parse (unmarshal) a kerberostime from a DER input stream. This form
* parsing might be used when expanding a value which is part of * parsing might be used when expanding a value which is part of
* a constructed sequence and uses explicitly tagged type. * a constructed sequence and uses explicitly tagged type.
* *
* @exception Asn1Exception on error. * @exception Asn1Exception on error.
* @param data the Der input stream value, which contains one or more marshaled value. * @param data the Der input stream value, which contains
* one or more marshaled value.
* @param explicitTag tag number. * @param explicitTag tag number.
* @param optional indicates if this data field is optional * @param optional indicates if this data field is optional
* @return an instance of KerberosTime. * @return an instance of KerberosTime.
* *
*/ */
public static KerberosTime parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException { public static KerberosTime parse(
DerInputStream data, byte explicitTag, boolean optional)
throws Asn1Exception, IOException {
if ((optional) && (((byte)data.peekByte() & (byte)0x1F)!= explicitTag)) if ((optional) && (((byte)data.peekByte() & (byte)0x1F)!= explicitTag))
return null; return null;
DerValue der = data.getDerValue(); DerValue der = data.getDerValue();
@ -343,7 +278,8 @@ public class KerberosTime implements Cloneable {
} }
else { else {
DerValue subDer = der.getData().getDerValue(); DerValue subDer = der.getData().getDerValue();
return new KerberosTime(subDer); Date temp = subDer.getGeneralizedTime();
return new KerberosTime(temp.getTime(), 0);
} }
} }

View File

@ -187,14 +187,10 @@ public class KrbCredInfo {
kcred.pname = (PrincipalName)pname.clone(); kcred.pname = (PrincipalName)pname.clone();
if (flags != null) if (flags != null)
kcred.flags = (TicketFlags)flags.clone(); kcred.flags = (TicketFlags)flags.clone();
if (authtime != null) kcred.authtime = authtime;
kcred.authtime = (KerberosTime)authtime.clone(); kcred.starttime = starttime;
if (starttime != null) kcred.endtime = endtime;
kcred.starttime = (KerberosTime)starttime.clone(); kcred.renewTill = renewTill;
if (endtime != null)
kcred.endtime = (KerberosTime)endtime.clone();
if (renewTill != null)
kcred.renewTill = (KerberosTime)renewTill.clone();
if (sname != null) if (sname != null)
kcred.sname = (PrincipalName)sname.clone(); kcred.sname = (PrincipalName)sname.clone();
if (caddr != null) if (caddr != null)

View File

@ -90,7 +90,7 @@ public class LastReqEntry {
public Object clone() { public Object clone() {
LastReqEntry newEntry = new LastReqEntry(); LastReqEntry newEntry = new LastReqEntry();
newEntry.lrType = lrType; newEntry.lrType = lrType;
newEntry.lrValue = (KerberosTime)lrValue.clone(); newEntry.lrValue = lrValue;
return newEntry; return newEntry;
} }
} }

View File

@ -65,7 +65,7 @@ public class PAEncTSEnc {
} }
public PAEncTSEnc() { public PAEncTSEnc() {
KerberosTime now = new KerberosTime(KerberosTime.NOW); KerberosTime now = KerberosTime.now();
pATimeStamp = now; pATimeStamp = now;
pAUSec = new Integer(now.getMicroSeconds()); pAUSec = new Integer(now.getMicroSeconds());
} }

View File

@ -68,14 +68,11 @@ public class Credentials {
sname = (PrincipalName) new_sname.clone(); sname = (PrincipalName) new_sname.clone();
key = (EncryptionKey) new_key.clone(); key = (EncryptionKey) new_key.clone();
authtime = (KerberosTime) new_authtime.clone(); authtime = new_authtime;
if (new_starttime != null) { starttime = new_starttime;
starttime = (KerberosTime) new_starttime.clone(); endtime = new_endtime;
} renewTill = new_renewTill;
endtime = (KerberosTime) new_endtime.clone();
if (new_renewTill != null) {
renewTill = (KerberosTime) new_renewTill.clone();
}
if (new_caddr != null) { if (new_caddr != null) {
caddr = (HostAddresses) new_caddr.clone(); caddr = (HostAddresses) new_caddr.clone();
} }
@ -104,14 +101,11 @@ public class Credentials {
ticket = (Ticket) kdcRep.ticket.clone(); ticket = (Ticket) kdcRep.ticket.clone();
key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone(); key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone();
flags = (TicketFlags) kdcRep.encKDCRepPart.flags.clone(); flags = (TicketFlags) kdcRep.encKDCRepPart.flags.clone();
authtime = (KerberosTime) kdcRep.encKDCRepPart.authtime.clone(); authtime = kdcRep.encKDCRepPart.authtime;
if (kdcRep.encKDCRepPart.starttime != null) { starttime = kdcRep.encKDCRepPart.starttime;
starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone(); endtime = kdcRep.encKDCRepPart.endtime;
} renewTill = kdcRep.encKDCRepPart.renewTill;
endtime = (KerberosTime) kdcRep.encKDCRepPart.endtime.clone();
if (kdcRep.encKDCRepPart.renewTill != null) {
renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone();
}
sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone(); sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone();
caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone(); caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone();
secondTicket = (Ticket) new_secondTicket.clone(); secondTicket = (Ticket) new_secondTicket.clone();
@ -128,18 +122,10 @@ public class Credentials {
sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone(); sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone();
cname = (PrincipalName) kdcRep.cname.clone(); cname = (PrincipalName) kdcRep.cname.clone();
key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone(); key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone();
authtime = (KerberosTime) kdcRep.encKDCRepPart.authtime.clone(); authtime = kdcRep.encKDCRepPart.authtime;
if (kdcRep.encKDCRepPart.starttime != null) { starttime = kdcRep.encKDCRepPart.starttime;
starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone(); endtime = kdcRep.encKDCRepPart.endtime;
} else { renewTill = kdcRep.encKDCRepPart.renewTill;
starttime = null;
}
endtime = (KerberosTime) kdcRep.encKDCRepPart.endtime.clone();
if (kdcRep.encKDCRepPart.renewTill != null) {
renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone();
} else {
renewTill = null;
}
// if (kdcRep.msgType == Krb5.KRB_AS_REP) { // if (kdcRep.msgType == Krb5.KRB_AS_REP) {
// isEncInSKey = false; // isEncInSKey = false;
// secondTicket = null; // secondTicket = null;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2013, 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
@ -101,7 +101,7 @@ abstract class SHA2 extends DigestBase {
i2bBig4((int)bitsProcessed, buffer, 60); i2bBig4((int)bitsProcessed, buffer, 60);
implCompress(buffer, 0); implCompress(buffer, 0);
i2bBig(state, 0, out, ofs, 32); i2bBig(state, 0, out, ofs, engineGetDigestLength());
} }
/** /**

View File

@ -843,5 +843,52 @@ public final class UntrustedCertificates {
"zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" + "zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" +
"-----END CERTIFICATE-----"); "-----END CERTIFICATE-----");
//
// Revoked code signing certificate w/ a stolen key issued by GoDaddy
// used to sign malware
//
// Subject: CN=CLEARESULT CONSULTING INC., OU=Corporate IT,
// O=CLEARESULT CONSULTING INC., L=Austin, ST=TX, C=US
// Issuer: SERIALNUMBER=07969287,
// CN=Go Daddy Secure Certification Authority,
// OU=http://certificates.godaddy.com/repository,
// O="GoDaddy.com, Inc.",
// L=Scottsdale,
// ST=Arizona,
// C=US
// Serial: 2b:73:43:2a:a8:4f:44
add("clearesult-consulting-inc-2AA84F44",
"-----BEGIN CERTIFICATE-----\n" +
"MIIFYjCCBEqgAwIBAgIHK3NDKqhPRDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE\n" +
"BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY\n" +
"BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm\n" +
"aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5\n" +
"IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky\n" +
"ODcwHhcNMTIwMjE1MjEwOTA2WhcNMTQwMjE1MjEwOTA2WjCBjDELMAkGA1UEBgwC\n" +
"VVMxCzAJBgNVBAgMAlRYMQ8wDQYDVQQHDAZBdXN0aW4xIzAhBgNVBAoMGkNMRUFS\n" +
"RVNVTFQgQ09OU1VMVElORyBJTkMuMRUwEwYDVQQLDAxDb3Jwb3JhdGUgSVQxIzAh\n" +
"BgNVBAMMGkNMRUFSRVNVTFQgQ09OU1VMVElORyBJTkMuMIIBIjANBgkqhkiG9w0B\n" +
"AQEFAAOCAQ8AMIIBCgKCAQEAtIOjCKeAicull+7ZIzt0/4ya3IeXUFlfypqKMLkU\n" +
"IbKjn0P5uMj6VE3rlbZr44RCegxvdnR6umBh1c0ZXoN3o+yc0JKcKcLiApmJJ277\n" +
"p7IbLwYDhBXRQNoIJm187IOMRPIxsKN4hL91txn9jGBmW+9zKlJlNhR5R7vjwU2E\n" +
"jrH/6oqsc9EM2yYpfjlNv6+3jSwAYZCkSWr+27PQOV+YHKmIxtJjX0upFz5FdIrV\n" +
"9CCX+L2Kji1THOkSgG4QTbYxmEcHqGViWz8hXLeNXjcbEsPuIiAu3hknxRHfUTE/\n" +
"U0Lh0Ug1e3LrJu+WnxM2SmUY4krsZ22c0yWUW9hzWITIjQIDAQABo4IBhzCCAYMw\n" +
"DwYDVR0TAQH/BAUwAwEBADATBgNVHSUEDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8E\n" +
"BAMCB4AwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9n\n" +
"ZHM1LTE2LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcCMDkwNwYIKwYBBQUH\n" +
"AgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8w\n" +
"gYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRk\n" +
"eS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHku\n" +
"Y29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9\n" +
"rGEyk2xF1uLuhV+auud2mWjM5zAdBgNVHQ4EFgQUDtdeKqeN2QkcbEp1HovFieNB\n" +
"XiowDQYJKoZIhvcNAQEFBQADggEBAD74Agw5tvi2aBl4/f/s7/VE/BClzDsKMb9K\n" +
"v9qpeC45ZA/jelxV11HKbQnVF194gDb7D2H9OsAsRUy8HVKbXEcc/8dKvwOqb+BC\n" +
"2i/EmfjLgmCfezNFtLq8xcPxF3zIRc44vPrK0z4YZsaHdH+yTEJ51p5EMdTqaLaP\n" +
"4n5m8LX3RfqlQB9dYFe6dUoYZjKm9d/pIRww3VqfOzjl42Edi1w6dWmBVMx1NZuR\n" +
"DBabJH1vJ9Gd+KwxMCmBZ6pQPl28JDimhJhI2LNqU349uADQVV0HJosddN/ARyyI\n" +
"LSIQO7BnNVKVG9Iujf33bvPNeg0qNz5qw+rKKq97Pqeum+L5oKU=\n" +
"-----END CERTIFICATE-----");
} }
} }

View File

@ -350,16 +350,21 @@ JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim);
/* /*
* java.lang.Class and java.lang.ClassLoader * java.lang.Class and java.lang.ClassLoader
*/ */
#define JVM_DEPTH -1
/* /*
* Returns the class in which the code invoking the native method * Returns the immediate caller class of the native method invoking
* belongs. * JVM_GetCallerClass. The Method.invoke and other frames due to
* reflection machinery are skipped.
* *
* Note that in JDK 1.1, native methods did not create a frame. * The depth parameter must be -1 (JVM_DEPTH). The caller is expected
* In 1.2, they do. Therefore native methods like Class.forName * to be marked with sun.reflect.CallerSensitive. The JVM will throw
* can no longer look at the current frame for the caller class. * an error if it is not marked propertly.
*/ */
JNIEXPORT jclass JNICALL JNIEXPORT jclass JNICALL
JVM_GetCallerClass(JNIEnv *env, int n); JVM_GetCallerClass(JNIEnv *env, int depth);
/* /*
* Find primitive classes * Find primitive classes

View File

@ -177,23 +177,36 @@ keystore.type=jks
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # been granted.
package.access=sun.,\ package.access=sun.,\
com.sun.xml.internal.bind.,\ com.sun.xml.internal.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\ com.sun.imageio.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\ com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\ com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.glassfish.gmbal.,\ com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\ com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\ com.oracle.webservices.internal.,\
jdk.internal.,\ jdk.internal.,\
jdk.nashorn.internal.,\ jdk.nashorn.internal.,\
jdk.nashorn.tools. jdk.nashorn.tools.
# #
# List of comma-separated packages that start with or equal this string # List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when # will cause a security exception to be thrown when
@ -205,23 +218,36 @@ package.access=sun.,\
# checkPackageDefinition. # checkPackageDefinition.
# #
package.definition=sun.,\ package.definition=sun.,\
com.sun.xml.internal.bind.,\ com.sun.xml.internal.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\ com.sun.imageio.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\ com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\ com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.glassfish.gmbal.,\ com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\ com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\ com.oracle.webservices.internal.,\
jdk.internal.,\ jdk.internal.,\
jdk.nashorn.internal.,\ jdk.nashorn.internal.,\
jdk.nashorn.tools. jdk.nashorn.tools.
# #
# Determines whether this properties file can be appended to # Determines whether this properties file can be appended to
# or overridden on the command line via -Djava.security.properties # or overridden on the command line via -Djava.security.properties

View File

@ -178,17 +178,29 @@ keystore.type=jks
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # been granted.
package.access=sun.,\ package.access=sun.,\
com.sun.xml.internal.bind.,\ com.sun.xml.internal.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\ com.sun.imageio.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\ com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\ com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.glassfish.gmbal.,\ com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\ com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\ com.oracle.webservices.internal.,\
jdk.internal.,\ jdk.internal.,\
@ -207,17 +219,29 @@ package.access=sun.,\
# checkPackageDefinition. # checkPackageDefinition.
# #
package.definition=sun.,\ package.definition=sun.,\
com.sun.xml.internal.bind.,\ com.sun.xml.internal.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\ com.sun.imageio.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\ com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\ com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.glassfish.gmbal.,\ com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\ com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\ com.oracle.webservices.internal.,\
jdk.internal.,\ jdk.internal.,\

View File

@ -179,17 +179,29 @@ keystore.type=jks
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # been granted.
package.access=sun.,\ package.access=sun.,\
com.sun.xml.internal.bind.,\ com.sun.xml.internal.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\ com.sun.imageio.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\ com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\ com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.glassfish.gmbal.,\ com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\ com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\ com.oracle.webservices.internal.,\
jdk.internal.,\ jdk.internal.,\
@ -207,17 +219,29 @@ package.access=sun.,\
# checkPackageDefinition. # checkPackageDefinition.
# #
package.definition=sun.,\ package.definition=sun.,\
com.sun.xml.internal.bind.,\ com.sun.xml.internal.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\ com.sun.imageio.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\ com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\ com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.glassfish.gmbal.,\ com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\ com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\ com.oracle.webservices.internal.,\
jdk.internal.,\ jdk.internal.,\

View File

@ -178,22 +178,35 @@ keystore.type=jks
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # been granted.
package.access=sun.,\ package.access=sun.,\
com.sun.xml.internal.bind.,\ com.sun.xml.internal.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\ com.sun.imageio.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\ com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\ com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.glassfish.gmbal.,\ com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\ com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\ com.oracle.webservices.internal.,\
jdk.internal.,\ jdk.internal.,\
jdk.nashorn.internal.,\ jdk.nashorn.internal.,\
jdk.nashorn.tools. jdk.nashorn.tools.,\
com.sun.java.accessibility.
# #
# List of comma-separated packages that start with or equal this string # List of comma-separated packages that start with or equal this string
@ -206,22 +219,35 @@ package.access=sun.,\
# checkPackageDefinition. # checkPackageDefinition.
# #
package.definition=sun.,\ package.definition=sun.,\
com.sun.xml.internal.bind.,\ com.sun.xml.internal.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.imageio.,\ com.sun.imageio.,\
com.sun.istack.internal.,\ com.sun.istack.internal.,\
com.sun.jmx.,\ com.sun.jmx.,\
com.sun.proxy.,\ com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\ com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\ com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.glassfish.gmbal.,\ com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\ com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\ com.oracle.webservices.internal.,\
jdk.internal.,\ jdk.internal.,\
jdk.nashorn.internal.,\ jdk.nashorn.internal.,\
jdk.nashorn.tools. jdk.nashorn.tools.,\
com.sun.java.accessibility.
# #
# Determines whether this properties file can be appended to # Determines whether this properties file can be appended to

Some files were not shown because too many files have changed in this diff Show More