diff --git a/.hgtags b/.hgtags
index 686a57f644052ebb9f99b20bfea96797e5066c86..b68c2ddabee1c498292847541c1c85d944e4fe29 100644
--- a/.hgtags
+++ b/.hgtags
@@ -997,3 +997,6 @@ e880f2d161bf23a09f8c1a19861d7df7d2ed126f jdk8u222-b01
c7a97c9b7e5932d651eda37c8a907311818491d7 jdk8u222-b07
0bb89d93d4d7da64d408a9888df21085e7bfb291 jdk8u222-b08
887c8314411dd461ec4b1e14cd6368ed3d9a7a3b jdk8u232-b00
+0da125166b2bd35aac0d6222ba44535730e2713f jdk8u222-b09
+2a9bea6e5e03a53469abdcd2da268a312cc7b5b8 jdk8u222-b10
+2a9bea6e5e03a53469abdcd2da268a312cc7b5b8 jdk8u222-ga
diff --git a/src/macosx/native/java/util/SCDynamicStoreConfig.m b/src/macosx/native/java/util/SCDynamicStoreConfig.m
index d3f838871ad7333c88f81d3cf837bada2a3e0017..4ea43635d46e88608c69d8161d7c5688ad4fd734 100644
--- a/src/macosx/native/java/util/SCDynamicStoreConfig.m
+++ b/src/macosx/native/java/util/SCDynamicStoreConfig.m
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -102,7 +102,8 @@ NSDictionary *realmConfigsForRealms(SCDynamicStoreRef store, NSArray *realms) {
for (NSString *realm in realms) {
CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]);
- if (CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
+ if (realmInfo == NULL || CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
+ if (realmInfo) CFRelease(realmInfo);
return nil;
}
diff --git a/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m b/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m
index 07bbd43e0a516a6abeaa18601ea01648f88da184..0e228f31ef195e37b6a44974abb89a93da3ea885 100644
--- a/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m
+++ b/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -184,7 +184,7 @@ SplashInitPlatform(Splash * splash) {
splash->maskRequired = 0;
-
+
//TODO: the following is too much of a hack but should work in 90% cases.
// besides we don't use device-dependant drawing, so probably
// that's very fine indeed
@@ -251,9 +251,11 @@ void
SplashRedrawWindow(Splash * splash) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- SplashUpdateScreenData(splash);
-
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ // drop the reference to the old view and image
+ [splash->window setContentView: nil];
+ SplashUpdateScreenData(splash);
+
// NSDeviceRGBColorSpace vs. NSCalibratedRGBColorSpace ?
NSBitmapImageRep * rep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: (unsigned char**)&splash->screenData
@@ -281,7 +283,7 @@ SplashRedrawWindow(Splash * splash) {
size.height /= scaleFactor;
[image setSize: size];
}
-
+
NSImageView * view = [[NSImageView alloc] init];
[view setImage: image];
diff --git a/src/share/classes/com/sun/crypto/provider/AESCrypt.java b/src/share/classes/com/sun/crypto/provider/AESCrypt.java
index c85f715e96714d6262c39af5dec8f2712486b7fc..c74f609f3ad4a32ab144b673edbbe8916d14389f 100644
--- a/src/share/classes/com/sun/crypto/provider/AESCrypt.java
+++ b/src/share/classes/com/sun/crypto/provider/AESCrypt.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, 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
@@ -346,7 +346,15 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
* Encrypt exactly one block of plaintext.
*/
void encryptBlock(byte[] in, int inOffset,
- byte[] out, int outOffset)
+ byte[] out, int outOffset) {
+ // Array bound checks are done in caller code, i.e.
+ // FeedbackCipher.encrypt/decrypt(...) to improve performance.
+ implEncryptBlock(in, inOffset, out, outOffset);
+ }
+
+ // Encryption operation. Possibly replaced with a compiler intrinsic.
+ private void implEncryptBlock(byte[] in, int inOffset,
+ byte[] out, int outOffset)
{
int keyOffset = 0;
int t0 = ((in[inOffset++] ) << 24 |
@@ -412,12 +420,19 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt ));
}
-
/**
* Decrypt exactly one block of plaintext.
*/
void decryptBlock(byte[] in, int inOffset,
- byte[] out, int outOffset)
+ byte[] out, int outOffset) {
+ // Array bound checks are done in caller code, i.e.
+ // FeedbackCipher.encrypt/decrypt(...) to improve performance.
+ implDecryptBlock(in, inOffset, out, outOffset);
+ }
+
+ // Decrypt operation. Possibly replaced with a compiler intrinsic.
+ private void implDecryptBlock(byte[] in, int inOffset,
+ byte[] out, int outOffset)
{
int keyOffset = 4;
int t0 = ((in[inOffset++] ) << 24 |
@@ -572,7 +587,6 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 ));
}
-
/**
* Expand a user-supplied key material into a session key.
*
diff --git a/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java b/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java
index 1d33117dd5d89b015d8775c1426850a9c67c07bb..7fdc6e1f67b22162a4b99afdbeef6a7822aabdfa 100644
--- a/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java
+++ b/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -27,7 +27,9 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException;
import java.security.ProviderException;
+import java.util.Objects;
+import sun.security.util.ArrayUtil;
/**
* This class represents ciphers in cipher block chaining (CBC) mode.
@@ -138,18 +140,24 @@ class CipherBlockChaining extends FeedbackCipher {
* @return the length of the encrypted data
*/
int encrypt(byte[] plain, int plainOffset, int plainLen,
- byte[] cipher, int cipherOffset)
- {
+ byte[] cipher, int cipherOffset) {
if (plainLen <= 0) {
return plainLen;
}
- if ((plainLen % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+ ArrayUtil.blockSizeCheck(plainLen, blockSize);
+ ArrayUtil.nullAndBoundsCheck(plain, plainOffset, plainLen);
+ ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, plainLen);
+ return implEncrypt(plain, plainOffset, plainLen,
+ cipher, cipherOffset);
+ }
+
+ private int implEncrypt(byte[] plain, int plainOffset, int plainLen,
+ byte[] cipher, int cipherOffset)
+ {
int endIndex = plainOffset + plainLen;
for (; plainOffset < endIndex;
- plainOffset+=blockSize, cipherOffset += blockSize) {
+ plainOffset += blockSize, cipherOffset += blockSize) {
for (int i = 0; i < blockSize; i++) {
k[i] = (byte)(plain[i + plainOffset] ^ r[i]);
}
@@ -182,14 +190,19 @@ class CipherBlockChaining extends FeedbackCipher {
* @return the length of the decrypted data
*/
int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
- byte[] plain, int plainOffset)
- {
+ byte[] plain, int plainOffset) {
if (cipherLen <= 0) {
return cipherLen;
}
- if ((cipherLen % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+ ArrayUtil.blockSizeCheck(cipherLen, blockSize);
+ ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, cipherLen);
+ ArrayUtil.nullAndBoundsCheck(plain, plainOffset, cipherLen);
+ return implDecrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
+ }
+
+ private int implDecrypt(byte[] cipher, int cipherOffset, int cipherLen,
+ byte[] plain, int plainOffset)
+ {
int endIndex = cipherOffset + cipherLen;
for (; cipherOffset < endIndex;
diff --git a/src/share/classes/com/sun/crypto/provider/CipherFeedback.java b/src/share/classes/com/sun/crypto/provider/CipherFeedback.java
index 84b527efe5b03afb2e7177b3c65b0b91deed4ae9..71e94cc7ffaee5ac1c7648e51e4025dbe6751cf6 100644
--- a/src/share/classes/com/sun/crypto/provider/CipherFeedback.java
+++ b/src/share/classes/com/sun/crypto/provider/CipherFeedback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException;
import java.security.ProviderException;
+import sun.security.util.ArrayUtil;
/**
* This class represents ciphers in cipher-feedback (CFB) mode.
@@ -149,9 +150,9 @@ final class CipherFeedback extends FeedbackCipher {
*/
int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) {
- if ((plainLen % numBytes) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+ ArrayUtil.blockSizeCheck(plainLen, numBytes);
+ ArrayUtil.nullAndBoundsCheck(plain, plainOffset, plainLen);
+ ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, plainLen);
int nShift = blockSize - numBytes;
int loopCount = plainLen / numBytes;
@@ -225,9 +226,10 @@ final class CipherFeedback extends FeedbackCipher {
*/
int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) {
- if ((cipherLen % numBytes) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+
+ ArrayUtil.blockSizeCheck(cipherLen, numBytes);
+ ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, cipherLen);
+ ArrayUtil.nullAndBoundsCheck(plain, plainOffset, cipherLen);
int nShift = blockSize - numBytes;
int loopCount = cipherLen / numBytes;
diff --git a/src/share/classes/com/sun/crypto/provider/CounterMode.java b/src/share/classes/com/sun/crypto/provider/CounterMode.java
index b810b8ff8c7611701fcf8d6fea45779635c8d8e2..cda5db2cf8505053fdc9707101627c06f90cf8d5 100644
--- a/src/share/classes/com/sun/crypto/provider/CounterMode.java
+++ b/src/share/classes/com/sun/crypto/provider/CounterMode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, 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
@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException;
+import sun.security.util.ArrayUtil;
/**
* This class represents ciphers in counter (CTR) mode.
@@ -173,6 +174,10 @@ final class CounterMode extends FeedbackCipher {
if (len == 0) {
return 0;
}
+
+ ArrayUtil.nullAndBoundsCheck(in, inOff, len);
+ ArrayUtil.nullAndBoundsCheck(out, outOff, len);
+
int result = len;
while (len-- > 0) {
if (used >= blockSize) {
diff --git a/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java b/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java
index 334e4245e27a5522000c75b10ea06f1bb2c558b5..24e85adb9ba888ba5471a7a5ccc311f821e7d659 100644
--- a/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java
+++ b/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException;
import java.security.ProviderException;
+import sun.security.util.ArrayUtil;
/**
* This class represents ciphers in electronic codebook (ECB) mode.
@@ -112,9 +113,10 @@ final class ElectronicCodeBook extends FeedbackCipher {
* @return the length of the encrypted data
*/
int encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
- if ((len % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+ ArrayUtil.blockSizeCheck(len, blockSize);
+ ArrayUtil.nullAndBoundsCheck(in, inOff, len);
+ ArrayUtil.nullAndBoundsCheck(out, outOff, len);
+
for (int i = len; i >= blockSize; i -= blockSize) {
embeddedCipher.encryptBlock(in, inOff, out, outOff);
inOff += blockSize;
@@ -141,9 +143,10 @@ final class ElectronicCodeBook extends FeedbackCipher {
* @return the length of the decrypted data
*/
int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
- if ((len % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+ ArrayUtil.blockSizeCheck(len, blockSize);
+ ArrayUtil.nullAndBoundsCheck(in, inOff, len);
+ ArrayUtil.nullAndBoundsCheck(out, outOff, len);
+
for (int i = len; i >= blockSize; i -= blockSize) {
embeddedCipher.decryptBlock(in, inOff, out, outOff);
inOff += blockSize;
diff --git a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
index cdb22d1217919c632e1b427289382c6899163337..b574848704c44a8b972a56d9433054e16d346560 100644
--- a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
+++ b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, 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
@@ -30,6 +30,8 @@ import java.io.*;
import java.security.*;
import javax.crypto.*;
import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
+import sun.security.util.ArrayUtil;
+
/**
* This class represents ciphers in GaloisCounter (GCM) mode.
@@ -406,8 +408,8 @@ final class GaloisCounterMode extends FeedbackCipher {
/**
* Performs encryption operation.
*
- *
The input plain text in, starting at inOff
- * and ending at (inOff + len - 1), is encrypted. The result
+ *
The input plain text in, starting at inOfs
+ * and ending at (inOfs + len - 1), is encrypted. The result
* is stored in out, starting at outOfs.
*
* @param in the buffer with the input data to be encrypted
@@ -422,15 +424,18 @@ final class GaloisCounterMode extends FeedbackCipher {
int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
checkDataLength(processed, len);
- if ((len % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+ ArrayUtil.blockSizeCheck(len, blockSize);
processAAD();
+
if (len > 0) {
+ ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
+ ArrayUtil.nullAndBoundsCheck(out, outOfs, len);
+
gctrPAndC.update(in, inOfs, len, out, outOfs);
processed += len;
ghashAllToS.update(out, outOfs, len);
}
+
return len;
}
@@ -450,7 +455,10 @@ final class GaloisCounterMode extends FeedbackCipher {
throw new ShortBufferException
("Can't fit both data and tag into one buffer");
}
- if (out.length - outOfs < (len + tagLenBytes)) {
+ try {
+ ArrayUtil.nullAndBoundsCheck(out, outOfs,
+ (len + tagLenBytes));
+ } catch (ArrayIndexOutOfBoundsException aiobe) {
throw new ShortBufferException("Output buffer too small");
}
@@ -458,6 +466,8 @@ final class GaloisCounterMode extends FeedbackCipher {
processAAD();
if (len > 0) {
+ ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
+
doLastBlock(in, inOfs, len, out, outOfs, true);
}
@@ -493,15 +503,14 @@ final class GaloisCounterMode extends FeedbackCipher {
int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
checkDataLength(ibuffer.size(), len);
- if ((len % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+ ArrayUtil.blockSizeCheck(len, blockSize);
processAAD();
if (len > 0) {
// store internally until decryptFinal is called because
// spec mentioned that only return recovered data after tag
// is successfully verified
+ ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
ibuffer.write(in, inOfs, len);
}
return 0;
@@ -530,22 +539,28 @@ final class GaloisCounterMode extends FeedbackCipher {
if (len < tagLenBytes) {
throw new AEADBadTagException("Input too short - need tag");
}
+
// do this check here can also catch the potential integer overflow
// scenario for the subsequent output buffer capacity check.
checkDataLength(ibuffer.size(), (len - tagLenBytes));
- if (out.length - outOfs < ((ibuffer.size() + len) - tagLenBytes)) {
+ try {
+ ArrayUtil.nullAndBoundsCheck(out, outOfs,
+ (ibuffer.size() + len) - tagLenBytes);
+ } catch (ArrayIndexOutOfBoundsException aiobe) {
throw new ShortBufferException("Output buffer too small");
}
processAAD();
+ ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
+
// get the trailing tag bytes from 'in'
byte[] tag = new byte[tagLenBytes];
System.arraycopy(in, inOfs + len - tagLenBytes, tag, 0, tagLenBytes);
len -= tagLenBytes;
- if (len != 0) {
+ if (len > 0) {
ibuffer.write(in, inOfs, len);
}
diff --git a/src/share/classes/com/sun/crypto/provider/OutputFeedback.java b/src/share/classes/com/sun/crypto/provider/OutputFeedback.java
index 47d9d63c93df6efbfa5a9e69a506193a5f210de4..7b518836cd1cfe0c37705acf347218a8a8e3cf89 100644
--- a/src/share/classes/com/sun/crypto/provider/OutputFeedback.java
+++ b/src/share/classes/com/sun/crypto/provider/OutputFeedback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException;
import java.security.ProviderException;
+import sun.security.util.ArrayUtil;
/**
* This class represents ciphers in output-feedback (OFB) mode.
@@ -148,10 +149,10 @@ final class OutputFeedback extends FeedbackCipher {
*/
int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) {
+ ArrayUtil.blockSizeCheck(plainLen, numBytes);
+ ArrayUtil.nullAndBoundsCheck(plain, plainOffset, plainLen);
+ ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, plainLen);
- if ((plainLen % numBytes) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
int nShift = blockSize - numBytes;
int loopCount = plainLen / numBytes;
@@ -189,6 +190,9 @@ final class OutputFeedback extends FeedbackCipher {
*/
int encryptFinal(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) {
+ ArrayUtil.nullAndBoundsCheck(plain, plainOffset, plainLen);
+ ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, plainLen);
+
int oddBytes = plainLen % numBytes;
int len = encrypt(plain, plainOffset, (plainLen - oddBytes),
cipher, cipherOffset);
diff --git a/src/share/classes/com/sun/crypto/provider/PCBC.java b/src/share/classes/com/sun/crypto/provider/PCBC.java
index fd99bb0cbd51208bc0c9d152df59d0e8fa59beaf..544776ec04fe07d25602708370297221bcbecec5 100644
--- a/src/share/classes/com/sun/crypto/provider/PCBC.java
+++ b/src/share/classes/com/sun/crypto/provider/PCBC.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException;
import java.security.ProviderException;
+import sun.security.util.ArrayUtil;
/**
@@ -136,9 +137,10 @@ final class PCBC extends FeedbackCipher {
int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset)
{
- if ((plainLen % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+ ArrayUtil.blockSizeCheck(plainLen, blockSize);
+ ArrayUtil.nullAndBoundsCheck(plain, plainOffset, plainLen);
+ ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, plainLen);
+
int i;
int endIndex = plainOffset + plainLen;
@@ -176,9 +178,10 @@ final class PCBC extends FeedbackCipher {
int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset)
{
- if ((cipherLen % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
+ ArrayUtil.blockSizeCheck(cipherLen, blockSize);
+ ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, cipherLen);
+ ArrayUtil.nullAndBoundsCheck(plain, plainOffset, cipherLen);
+
int i;
int endIndex = cipherOffset + cipherLen;
diff --git a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java
index 5c93d89e0e7f9b89510a2b0298e2e9b0bfb73978..8f58f5b3e6d5c4c66331996251ace1e5d8d00929 100644
--- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java
+++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -374,7 +374,10 @@ public class JPEGImageReader extends ImageReader {
// And set current image since we've read it now
currentImage = 0;
}
- if (seekForwardOnly) {
+ // If the image positions list is empty as in the case of a tables-only
+ // stream, then attempting to access the element at index
+ // imagePositions.size() - 1 will cause an IndexOutOfBoundsException.
+ if (seekForwardOnly && !imagePositions.isEmpty()) {
Long pos = (Long) imagePositions.get(imagePositions.size()-1);
iis.flushBefore(pos.longValue());
}
@@ -491,6 +494,11 @@ public class JPEGImageReader extends ImageReader {
if (!tablesOnlyChecked) {
checkTablesOnly();
}
+ // If the image positions list is empty as in the case of a tables-only
+ // stream, then no image data can be read.
+ if (imagePositions.isEmpty()) {
+ throw new IIOException("No image data present to read");
+ }
if (imageIndex < imagePositions.size()) {
iis.seek(((Long)(imagePositions.get(imageIndex))).longValue());
} else {
diff --git a/src/share/classes/java/lang/Throwable.java b/src/share/classes/java/lang/Throwable.java
index 4b9e2ad0415a7031ff48d98effc6d406730d9d85..34440fa2c5c400dcc0313e4e1ae8bd05c955cc43 100644
--- a/src/share/classes/java/lang/Throwable.java
+++ b/src/share/classes/java/lang/Throwable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,9 @@
*/
package java.lang;
-import java.io.*;
-import java.util.*;
+
+import java.io.*;
+import java.util.*;
/**
* The {@code Throwable} class is the superclass of all errors and
@@ -912,25 +913,37 @@ public class Throwable implements Serializable {
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject(); // read in all fields
- if (suppressedExceptions != null) {
- List suppressed = null;
- if (suppressedExceptions.isEmpty()) {
- // Use the sentinel for a zero-length list
- suppressed = SUPPRESSED_SENTINEL;
- } else { // Copy Throwables to new list
- suppressed = new ArrayList<>(1);
- for (Throwable t : suppressedExceptions) {
+
+ // Set suppressed exceptions and stack trace elements fields
+ // to marker values until the contents from the serial stream
+ // are validated.
+ List candidateSuppressedExceptions = suppressedExceptions;
+ suppressedExceptions = SUPPRESSED_SENTINEL;
+
+ StackTraceElement[] candidateStackTrace = stackTrace;
+ stackTrace = UNASSIGNED_STACK.clone();
+
+ if (candidateSuppressedExceptions != null) {
+ int suppressedSize = validateSuppressedExceptionsList(candidateSuppressedExceptions);
+ if (suppressedSize > 0) { // Copy valid Throwables to new list
+ List suppList = new ArrayList(Math.min(100, suppressedSize));
+
+ for (Throwable t : candidateSuppressedExceptions) {
// Enforce constraints on suppressed exceptions in
// case of corrupt or malicious stream.
if (t == null)
throw new NullPointerException(NULL_CAUSE_MESSAGE);
if (t == this)
throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
- suppressed.add(t);
+ suppList.add(t);
}
+ // If there are any invalid suppressed exceptions,
+ // implicitly use the sentinel value assigned earlier.
+ suppressedExceptions = suppList;
}
- suppressedExceptions = suppressed;
- } // else a null suppressedExceptions field remains null
+ } else {
+ suppressedExceptions = null;
+ }
/*
* For zero-length stack traces, use a clone of
@@ -941,25 +954,41 @@ public class Throwable implements Serializable {
* the stackTrace needs to be constructed from the information
* in backtrace.
*/
- if (stackTrace != null) {
- if (stackTrace.length == 0) {
- stackTrace = UNASSIGNED_STACK.clone();
- } else if (stackTrace.length == 1 &&
+ if (candidateStackTrace != null) {
+ // Work from a clone of the candidateStackTrace to ensure
+ // consistency of checks.
+ candidateStackTrace = candidateStackTrace.clone();
+ if (candidateStackTrace.length >= 1) {
+ if (candidateStackTrace.length == 1 &&
// Check for the marker of an immutable stack trace
- SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
- stackTrace = null;
- } else { // Verify stack trace elements are non-null.
- for(StackTraceElement ste : stackTrace) {
- if (ste == null)
- throw new NullPointerException("null StackTraceElement in serial stream. ");
+ SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(candidateStackTrace[0])) {
+ stackTrace = null;
+ } else { // Verify stack trace elements are non-null.
+ for (StackTraceElement ste : candidateStackTrace) {
+ if (ste == null)
+ throw new NullPointerException("null StackTraceElement in serial stream.");
+ }
+ stackTrace = candidateStackTrace;
}
}
+ }
+ // A null stackTrace field in the serial form can result from
+ // an exception serialized without that field in older JDK
+ // releases; treat such exceptions as having empty stack
+ // traces by leaving stackTrace assigned to a clone of
+ // UNASSIGNED_STACK.
+ }
+
+ private int validateSuppressedExceptionsList(List deserSuppressedExceptions)
+ throws IOException {
+ if (Object.class.getClassLoader() != deserSuppressedExceptions.getClass().getClassLoader()) {
+ throw new StreamCorruptedException("List implementation not on the bootclasspath.");
} else {
- // A null stackTrace field in the serial form can result
- // from an exception serialized without that field in
- // older JDK releases; treat such exceptions as having
- // empty stack traces.
- stackTrace = UNASSIGNED_STACK.clone();
+ int size = deserSuppressedExceptions.size();
+ if (size < 0) {
+ throw new StreamCorruptedException("Negative list size reported.");
+ }
+ return size;
}
}
diff --git a/src/share/classes/java/net/URL.java b/src/share/classes/java/net/URL.java
index 919825adbb62c0067d259a36ca12359e133e97f2..be6c294d191588c49e493d8ecce2f678b36b38e2 100644
--- a/src/share/classes/java/net/URL.java
+++ b/src/share/classes/java/net/URL.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@ import java.io.ObjectStreamField;
import java.io.ObjectInputStream.GetField;
import java.util.Hashtable;
import java.util.StringTokenizer;
+import sun.net.util.IPAddressUtil;
import sun.security.util.SecurityConstants;
/**
@@ -414,13 +415,19 @@ public final class URL implements java.io.Serializable {
}
ref = parts.getRef();
- // Note: we don't do validation of the URL here. Too risky to change
+ // Note: we don't do full validation of the URL here. Too risky to change
// right now, but worth considering for future reference. -br
if (handler == null &&
(handler = getURLStreamHandler(protocol)) == null) {
throw new MalformedURLException("unknown protocol: " + protocol);
}
this.handler = handler;
+ if (host != null && isBuiltinStreamHandler(handler)) {
+ String s = IPAddressUtil.checkExternalForm(this);
+ if (s != null) {
+ throw new MalformedURLException(s);
+ }
+ }
}
/**
@@ -943,7 +950,12 @@ public final class URL implements java.io.Serializable {
* @since 1.5
*/
public URI toURI() throws URISyntaxException {
- return new URI (toString());
+ URI uri = new URI(toString());
+ if (authority != null && isBuiltinStreamHandler(handler)) {
+ String s = IPAddressUtil.checkAuthority(this);
+ if (s != null) throw new URISyntaxException(authority, s);
+ }
+ return uri;
}
/**
@@ -1400,6 +1412,10 @@ public final class URL implements java.io.Serializable {
return replacementURL;
}
+ boolean isBuiltinStreamHandler(URLStreamHandler handler) {
+ return isBuiltinStreamHandler(handler.getClass().getName());
+ }
+
private boolean isBuiltinStreamHandler(String handlerClassName) {
return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
}
diff --git a/src/share/classes/java/net/URLStreamHandler.java b/src/share/classes/java/net/URLStreamHandler.java
index 513055982c76df9f6efc89a8e3b85dd1a7a29784..cbdf02a5eea6c72ba7df0fd764e63d98efad7d80 100644
--- a/src/share/classes/java/net/URLStreamHandler.java
+++ b/src/share/classes/java/net/URLStreamHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -532,12 +532,15 @@ public abstract class URLStreamHandler {
* @see java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
* @since 1.3
*/
- protected void setURL(URL u, String protocol, String host, int port,
+ protected void setURL(URL u, String protocol, String host, int port,
String authority, String userInfo, String path,
String query, String ref) {
if (this != u.handler) {
throw new SecurityException("handler for url different from " +
"this handler");
+ } else if (host != null && u.isBuiltinStreamHandler(this)) {
+ String s = IPAddressUtil.checkHostString(host);
+ if (s != null) throw new IllegalArgumentException(s);
}
// ensure that no one can reset the protocol on a given URL.
u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref);
diff --git a/src/share/classes/java/security/AccessController.java b/src/share/classes/java/security/AccessController.java
index 36408a8d633d5a21afc495e921785dcfc261bbbe..00e084ca96b8821a6e4cf6bccf6cd1672dd89150 100644
--- a/src/share/classes/java/security/AccessController.java
+++ b/src/share/classes/java/security/AccessController.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -425,7 +425,8 @@ public final class AccessController {
throw new NullPointerException("null permissions parameter");
}
Class > caller = Reflection.getCallerClass();
- return AccessController.doPrivileged(action, createWrapper(null,
+ DomainCombiner dc = (context == null) ? null : context.getCombiner();
+ return AccessController.doPrivileged(action, createWrapper(dc,
caller, parent, context, perms));
}
@@ -710,7 +711,8 @@ public final class AccessController {
throw new NullPointerException("null permissions parameter");
}
Class > caller = Reflection.getCallerClass();
- return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms));
+ DomainCombiner dc = (context == null) ? null : context.getCombiner();
+ return AccessController.doPrivileged(action, createWrapper(dc, caller, parent, context, perms));
}
diff --git a/src/share/classes/java/util/Collections.java b/src/share/classes/java/util/Collections.java
index 4dbdf8a5b41ada6c508fa5f291c1ddc5cdd57cee..79159eaa1106df60729e76d2c8ed099146360db5 100644
--- a/src/share/classes/java/util/Collections.java
+++ b/src/share/classes/java/util/Collections.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
package java.util;
import java.io.Serializable;
+import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
@@ -37,6 +38,7 @@ import java.util.function.UnaryOperator;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
+import sun.misc.SharedSecrets;
/**
* This class consists exclusively of static methods that operate on or return
@@ -5075,6 +5077,11 @@ public class Collections {
public Spliterator spliterator() {
return stream().spliterator();
}
+
+ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+ ois.defaultReadObject();
+ SharedSecrets.getJavaOISAccess().checkArray(ois, Object[].class, n);
+ }
}
/**
diff --git a/src/share/classes/jdk/internal/util/Preconditions.java b/src/share/classes/jdk/internal/util/Preconditions.java
new file mode 100644
index 0000000000000000000000000000000000000000..5be620d28a27fb9e7b4506a57387904cfa636554
--- /dev/null
+++ b/src/share/classes/jdk/internal/util/Preconditions.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2016, 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 jdk.internal.util;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+/**
+ * Utility methods to check if state or arguments are correct.
+ *
+ */
+public class Preconditions {
+
+ /**
+ * Maps out-of-bounds values to a runtime exception.
+ *
+ * @param checkKind the kind of bounds check, whose name may correspond
+ * to the name of one of the range check methods, checkIndex,
+ * checkFromToIndex, checkFromIndexSize
+ * @param args the out-of-bounds arguments that failed the range check.
+ * If the checkKind corresponds a the name of a range check method
+ * then the bounds arguments are those that can be passed in order
+ * to the method.
+ * @param oobef the exception formatter that when applied with a checkKind
+ * and a list out-of-bounds arguments returns a runtime exception.
+ * If {@code null} then, it is as if an exception formatter was
+ * supplied that returns {@link IndexOutOfBoundsException} for any
+ * given arguments.
+ * @return the runtime exception
+ */
+ private static RuntimeException outOfBounds(
+ BiFunction, ? extends RuntimeException> oobef,
+ String checkKind,
+ Integer... args) {
+ List largs = Collections.unmodifiableList(Arrays.asList(args));
+ RuntimeException e = oobef == null
+ ? null : oobef.apply(checkKind, largs);
+ return e == null
+ ? new IndexOutOfBoundsException(outOfBoundsMessage(checkKind, largs)) : e;
+ }
+
+ private static RuntimeException outOfBoundsCheckIndex(
+ BiFunction, ? extends RuntimeException> oobe,
+ int index, int length) {
+ return outOfBounds(oobe, "checkIndex", index, length);
+ }
+
+ private static RuntimeException outOfBoundsCheckFromToIndex(
+ BiFunction, ? extends RuntimeException> oobe,
+ int fromIndex, int toIndex, int length) {
+ return outOfBounds(oobe, "checkFromToIndex", fromIndex, toIndex, length);
+ }
+
+ private static RuntimeException outOfBoundsCheckFromIndexSize(
+ BiFunction, ? extends RuntimeException> oobe,
+ int fromIndex, int size, int length) {
+ return outOfBounds(oobe, "checkFromIndexSize", fromIndex, size, length);
+ }
+
+ /**
+ * Returns an out-of-bounds exception formatter from an given exception
+ * factory. The exception formatter is a function that formats an
+ * out-of-bounds message from its arguments and applies that message to the
+ * given exception factory to produce and relay an exception.
+ *
+ *
The exception formatter accepts two arguments: a {@code String}
+ * describing the out-of-bounds range check that failed, referred to as the
+ * check kind; and a {@code List} containing the
+ * out-of-bound integer values that failed the check. The list of
+ * out-of-bound values is not modified.
+ *
+ *
Three check kinds are supported {@code checkIndex},
+ * {@code checkFromToIndex} and {@code checkFromIndexSize} corresponding
+ * respectively to the specified application of an exception formatter as an
+ * argument to the out-of-bounds range check methods
+ * {@link #checkIndex(int, int, BiFunction) checkIndex},
+ * {@link #checkFromToIndex(int, int, int, BiFunction) checkFromToIndex}, and
+ * {@link #checkFromIndexSize(int, int, int, BiFunction) checkFromIndexSize}.
+ * Thus a supported check kind corresponds to a method name and the
+ * out-of-bound integer values correspond to method argument values, in
+ * order, preceding the exception formatter argument (similar in many
+ * respects to the form of arguments required for a reflective invocation of
+ * such a range check method).
+ *
+ *
Formatter arguments conforming to such supported check kinds will
+ * produce specific exception messages describing failed out-of-bounds
+ * checks. Otherwise, more generic exception messages will be produced in
+ * any of the following cases: the check kind is supported but fewer
+ * or more out-of-bounds values are supplied, the check kind is not
+ * supported, the check kind is {@code null}, or the list of out-of-bound
+ * values is {@code null}.
+ *
+ * @apiNote
+ * This method produces an out-of-bounds exception formatter that can be
+ * passed as an argument to any of the supported out-of-bounds range check
+ * methods declared by {@code Objects}. For example, a formatter producing
+ * an {@code ArrayIndexOutOfBoundsException} may be produced and stored on a
+ * {@code static final} field as follows:
+ *
+ * The formatter instance {@code AIOOBEF} may be passed as an argument to an
+ * out-of-bounds range check method, such as checking if an {@code index}
+ * is within the bounds of a {@code limit}:
+ *
+ * If the bounds check fails then the range check method will throw an
+ * {@code ArrayIndexOutOfBoundsException} with an appropriate exception
+ * message that is a produced from {@code AIOOBEF} as follows:
+ *
+ *
+ * @param f the exception factory, that produces an exception from a message
+ * where the message is produced and formatted by the returned
+ * exception formatter. If this factory is stateless and side-effect
+ * free then so is the returned formatter.
+ * Exceptions thrown by the factory are relayed to the caller
+ * of the returned formatter.
+ * @param the type of runtime exception to be returned by the given
+ * exception factory and relayed by the exception formatter
+ * @return the out-of-bounds exception formatter
+ */
+ public static
+ BiFunction, X> outOfBoundsExceptionFormatter(Function f) {
+ // Use anonymous class to avoid bootstrap issues if this method is
+ // used early in startup
+ return new BiFunction, X>() {
+ @Override
+ public X apply(String checkKind, List args) {
+ return f.apply(outOfBoundsMessage(checkKind, args));
+ }
+ };
+ }
+
+ private static String outOfBoundsMessage(String checkKind, List args) {
+ if (checkKind == null && args == null) {
+ return String.format("Range check failed");
+ } else if (checkKind == null) {
+ return String.format("Range check failed: %s", args);
+ } else if (args == null) {
+ return String.format("Range check failed: %s", checkKind);
+ }
+
+ int argSize = 0;
+ switch (checkKind) {
+ case "checkIndex":
+ argSize = 2;
+ break;
+ case "checkFromToIndex":
+ case "checkFromIndexSize":
+ argSize = 3;
+ break;
+ default:
+ }
+
+ // Switch to default if fewer or more arguments than required are supplied
+ switch ((args.size() != argSize) ? "" : checkKind) {
+ case "checkIndex":
+ return String.format("Index %d out-of-bounds for length %d",
+ args.get(0), args.get(1));
+ case "checkFromToIndex":
+ return String.format("Range [%d, %d) out-of-bounds for length %d",
+ args.get(0), args.get(1), args.get(2));
+ case "checkFromIndexSize":
+ return String.format("Range [%d, %The {@code index} is defined to be out-of-bounds if any of the
+ * following inequalities is true:
+ *
+ *
{@code index < 0}
+ *
{@code index >= length}
+ *
{@code length < 0}, which is implied from the former inequalities
+ *
+ *
+ *
If the {@code index} is out-of-bounds, then a runtime exception is
+ * thrown that is the result of applying the following arguments to the
+ * exception formatter: the name of this method, {@code checkIndex};
+ * and an unmodifiable list integers whose values are, in order, the
+ * out-of-bounds arguments {@code index} and {@code length}.
+ *
+ * @param the type of runtime exception to throw if the arguments are
+ * out-of-bounds
+ * @param index the index
+ * @param length the upper-bound (exclusive) of the range
+ * @param oobef the exception formatter that when applied with this
+ * method name and out-of-bounds arguments returns a runtime
+ * exception. If {@code null} or returns {@code null} then, it is as
+ * if an exception formatter produced from an invocation of
+ * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
+ * instead (though it may be more efficient).
+ * Exceptions thrown by the formatter are relayed to the caller.
+ * @return {@code index} if it is within bounds of the range
+ * @throws X if the {@code index} is out-of-bounds and the exception
+ * formatter is non-{@code null}
+ * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds
+ * and the exception formatter is {@code null}
+ * @since 9
+ *
+ * @implNote
+ * This method is made intrinsic in optimizing compilers to guide them to
+ * perform unsigned comparisons of the index and length when it is known the
+ * length is a non-negative value (such as that of an array length or from
+ * the upper bound of a loop)
+ */
+ public static
+ int checkIndex(int index, int length,
+ BiFunction, X> oobef) {
+ if (index < 0 || index >= length)
+ throw outOfBoundsCheckIndex(oobef, index, length);
+ return index;
+ }
+
+ /**
+ * Checks if the sub-range from {@code fromIndex} (inclusive) to
+ * {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
+ * (inclusive) to {@code length} (exclusive).
+ *
+ *
The sub-range is defined to be out-of-bounds if any of the following
+ * inequalities is true:
+ *
+ *
{@code fromIndex < 0}
+ *
{@code fromIndex > toIndex}
+ *
{@code toIndex > length}
+ *
{@code length < 0}, which is implied from the former inequalities
+ *
+ *
+ *
If the sub-range is out-of-bounds, then a runtime exception is
+ * thrown that is the result of applying the following arguments to the
+ * exception formatter: the name of this method, {@code checkFromToIndex};
+ * and an unmodifiable list integers whose values are, in order, the
+ * out-of-bounds arguments {@code fromIndex}, {@code toIndex}, and {@code length}.
+ *
+ * @param the type of runtime exception to throw if the arguments are
+ * out-of-bounds
+ * @param fromIndex the lower-bound (inclusive) of the sub-range
+ * @param toIndex the upper-bound (exclusive) of the sub-range
+ * @param length the upper-bound (exclusive) the range
+ * @param oobef the exception formatter that when applied with this
+ * method name and out-of-bounds arguments returns a runtime
+ * exception. If {@code null} or returns {@code null} then, it is as
+ * if an exception formatter produced from an invocation of
+ * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
+ * instead (though it may be more efficient).
+ * Exceptions thrown by the formatter are relayed to the caller.
+ * @return {@code fromIndex} if the sub-range within bounds of the range
+ * @throws X if the sub-range is out-of-bounds and the exception factory
+ * function is non-{@code null}
+ * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
+ * the exception factory function is {@code null}
+ * @since 9
+ */
+ public static
+ int checkFromToIndex(int fromIndex, int toIndex, int length,
+ BiFunction, X> oobef) {
+ if (fromIndex < 0 || fromIndex > toIndex || toIndex > length)
+ throw outOfBoundsCheckFromToIndex(oobef, fromIndex, toIndex, length);
+ return fromIndex;
+ }
+
+ /**
+ * Checks if the sub-range from {@code fromIndex} (inclusive) to
+ * {@code fromIndex + size} (exclusive) is within the bounds of range from
+ * {@code 0} (inclusive) to {@code length} (exclusive).
+ *
+ *
The sub-range is defined to be out-of-bounds if any of the following
+ * inequalities is true:
+ *
{@code length < 0}, which is implied from the former inequalities
+ *
+ *
+ *
If the sub-range is out-of-bounds, then a runtime exception is
+ * thrown that is the result of applying the following arguments to the
+ * exception formatter: the name of this method, {@code checkFromIndexSize};
+ * and an unmodifiable list integers whose values are, in order, the
+ * out-of-bounds arguments {@code fromIndex}, {@code size}, and
+ * {@code length}.
+ *
+ * @param the type of runtime exception to throw if the arguments are
+ * out-of-bounds
+ * @param fromIndex the lower-bound (inclusive) of the sub-interval
+ * @param size the size of the sub-range
+ * @param length the upper-bound (exclusive) of the range
+ * @param oobef the exception formatter that when applied with this
+ * method name and out-of-bounds arguments returns a runtime
+ * exception. If {@code null} or returns {@code null} then, it is as
+ * if an exception formatter produced from an invocation of
+ * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
+ * instead (though it may be more efficient).
+ * Exceptions thrown by the formatter are relayed to the caller.
+ * @return {@code fromIndex} if the sub-range within bounds of the range
+ * @throws X if the sub-range is out-of-bounds and the exception factory
+ * function is non-{@code null}
+ * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
+ * the exception factory function is {@code null}
+ * @since 9
+ */
+ public static
+ int checkFromIndexSize(int fromIndex, int size, int length,
+ BiFunction, X> oobef) {
+ if ((length | fromIndex | size) < 0 || size > length - fromIndex)
+ throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length);
+ return fromIndex;
+ }
+}
diff --git a/src/share/classes/sun/net/util/IPAddressUtil.java b/src/share/classes/sun/net/util/IPAddressUtil.java
index 6aa98c8f8d9ff84fb2e598c4a16283cc1d359acb..2bcd2c0781ca04b6a342dad60d9be046309ae1dd 100644
--- a/src/share/classes/sun/net/util/IPAddressUtil.java
+++ b/src/share/classes/sun/net/util/IPAddressUtil.java
@@ -25,6 +25,9 @@
package sun.net.util;
+import java.net.URL;
+import java.util.Arrays;
+
public class IPAddressUtil {
private final static int INADDR4SZ = 4;
private final static int INADDR16SZ = 16;
@@ -287,4 +290,182 @@ public class IPAddressUtil {
}
return false;
}
+
+ // See java.net.URI for more details on how to generate these
+ // masks.
+ //
+ // square brackets
+ private static final long L_IPV6_DELIMS = 0x0L; // "[]"
+ private static final long H_IPV6_DELIMS = 0x28000000L; // "[]"
+ // RFC 3986 gen-delims
+ private static final long L_GEN_DELIMS = 0x8400800800000000L; // ":/?#[]@"
+ private static final long H_GEN_DELIMS = 0x28000001L; // ":/?#[]@"
+ // These gen-delims can appear in authority
+ private static final long L_AUTH_DELIMS = 0x400000000000000L; // "@[]:"
+ private static final long H_AUTH_DELIMS = 0x28000001L; // "@[]:"
+ // colon is allowed in userinfo
+ private static final long L_COLON = 0x400000000000000L; // ":"
+ private static final long H_COLON = 0x0L; // ":"
+ // slash should be encoded in authority
+ private static final long L_SLASH = 0x800000000000L; // "/"
+ private static final long H_SLASH = 0x0L; // "/"
+ // backslash should always be encoded
+ private static final long L_BACKSLASH = 0x0L; // "\"
+ private static final long H_BACKSLASH = 0x10000000L; // "\"
+ // ASCII chars 0-31 + 127 - various controls + CRLF + TAB
+ private static final long L_NON_PRINTABLE = 0xffffffffL;
+ private static final long H_NON_PRINTABLE = 0x8000000000000000L;
+ // All of the above
+ private static final long L_EXCLUDE = 0x84008008ffffffffL;
+ private static final long H_EXCLUDE = 0x8000000038000001L;
+
+ private static final char[] OTHERS = {
+ 8263,8264,8265,8448,8449,8453,8454,10868,
+ 65109,65110,65119,65131,65283,65295,65306,65311,65312
+ };
+
+ // Tell whether the given character is found by the given mask pair
+ public static boolean match(char c, long lowMask, long highMask) {
+ if (c < 64)
+ return ((1L << c) & lowMask) != 0;
+ if (c < 128)
+ return ((1L << (c - 64)) & highMask) != 0;
+ return false; // other non ASCII characters are not filtered
+ }
+
+ // returns -1 if the string doesn't contain any characters
+ // from the mask, the index of the first such character found
+ // otherwise.
+ public static int scan(String s, long lowMask, long highMask) {
+ int i = -1, len;
+ if (s == null || (len = s.length()) == 0) return -1;
+ boolean match = false;
+ while (++i < len && !(match = match(s.charAt(i), lowMask, highMask)));
+ if (match) return i;
+ return -1;
+ }
+
+ public static int scan(String s, long lowMask, long highMask, char[] others) {
+ int i = -1, len;
+ if (s == null || (len = s.length()) == 0) return -1;
+ boolean match = false;
+ char c, c0 = others[0];
+ while (++i < len && !(match = match((c=s.charAt(i)), lowMask, highMask))) {
+ if (c >= c0 && (Arrays.binarySearch(others, c) > -1)) {
+ match = true; break;
+ }
+ }
+ if (match) return i;
+
+ return -1;
+ }
+
+ private static String describeChar(char c) {
+ if (c < 32 || c == 127) {
+ if (c == '\n') return "LF";
+ if (c == '\r') return "CR";
+ return "control char (code=" + (int)c + ")";
+ }
+ if (c == '\\') return "'\\'";
+ return "'" + c + "'";
+ }
+
+ private static String checkUserInfo(String str) {
+ // colon is permitted in user info
+ int index = scan(str, L_EXCLUDE & ~L_COLON,
+ H_EXCLUDE & ~H_COLON);
+ if (index >= 0) {
+ return "Illegal character found in user-info: "
+ + describeChar(str.charAt(index));
+ }
+ return null;
+ }
+
+ private static String checkHost(String str) {
+ int index;
+ if (str.startsWith("[") && str.endsWith("]")) {
+ str = str.substring(1, str.length() - 1);
+ if (isIPv6LiteralAddress(str)) {
+ index = str.indexOf('%');
+ if (index >= 0) {
+ index = scan(str = str.substring(index),
+ L_NON_PRINTABLE | L_IPV6_DELIMS,
+ H_NON_PRINTABLE | H_IPV6_DELIMS);
+ if (index >= 0) {
+ return "Illegal character found in IPv6 scoped address: "
+ + describeChar(str.charAt(index));
+ }
+ }
+ return null;
+ }
+ return "Unrecognized IPv6 address format";
+ } else {
+ index = scan(str, L_EXCLUDE, H_EXCLUDE);
+ if (index >= 0) {
+ return "Illegal character found in host: "
+ + describeChar(str.charAt(index));
+ }
+ }
+ return null;
+ }
+
+ private static String checkAuth(String str) {
+ int index = scan(str,
+ L_EXCLUDE & ~L_AUTH_DELIMS,
+ H_EXCLUDE & ~H_AUTH_DELIMS);
+ if (index >= 0) {
+ return "Illegal character found in authority: "
+ + describeChar(str.charAt(index));
+ }
+ return null;
+ }
+
+ // check authority of hierarchical URL. Appropriate for
+ // HTTP-like protocol handlers
+ public static String checkAuthority(URL url) {
+ String s, u, h;
+ if (url == null) return null;
+ if ((s = checkUserInfo(u = url.getUserInfo())) != null) {
+ return s;
+ }
+ if ((s = checkHost(h = url.getHost())) != null) {
+ return s;
+ }
+ if (h == null && u == null) {
+ return checkAuth(url.getAuthority());
+ }
+ return null;
+ }
+
+ // minimal syntax checks - deeper check may be performed
+ // by the appropriate protocol handler
+ public static String checkExternalForm(URL url) {
+ String s;
+ if (url == null) return null;
+ int index = scan(s = url.getUserInfo(),
+ L_NON_PRINTABLE | L_SLASH,
+ H_NON_PRINTABLE | H_SLASH);
+ if (index >= 0) {
+ return "Illegal character found in authority: "
+ + describeChar(s.charAt(index));
+ }
+ if ((s = checkHostString(url.getHost())) != null) {
+ return s;
+ }
+ return null;
+ }
+
+ public static String checkHostString(String host) {
+ if (host == null) return null;
+ int index = scan(host,
+ L_NON_PRINTABLE | L_SLASH,
+ H_NON_PRINTABLE | H_SLASH,
+ OTHERS);
+ if (index >= 0) {
+ return "Illegal character found in host: "
+ + describeChar(host.charAt(index));
+ }
+ return null;
+ }
+
}
diff --git a/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java b/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java
index e560abf9c287b7db69251ac6caf186a15ac075f3..582687ba46b6bf614da7498f917966e2af6b3fe6 100644
--- a/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java
+++ b/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@ import java.io.BufferedInputStream;
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
import java.net.URL;
import java.net.SocketPermission;
import java.net.UnknownHostException;
@@ -47,6 +48,7 @@ import java.util.StringTokenizer;
import java.util.Iterator;
import java.security.Permission;
import sun.net.NetworkClient;
+import sun.net.util.IPAddressUtil;
import sun.net.www.MessageHeader;
import sun.net.www.MeteredStream;
import sun.net.www.URLConnection;
@@ -155,6 +157,21 @@ public class FtpURLConnection extends URLConnection {
}
}
+ static URL checkURL(URL u) throws IllegalArgumentException {
+ if (u != null) {
+ if (u.toExternalForm().indexOf('\n') > -1) {
+ Exception mfue = new MalformedURLException("Illegal character in URL");
+ throw new IllegalArgumentException(mfue.getMessage(), mfue);
+ }
+ }
+ String s = IPAddressUtil.checkAuthority(u);
+ if (s != null) {
+ Exception mfue = new MalformedURLException(s);
+ throw new IllegalArgumentException(mfue.getMessage(), mfue);
+ }
+ return u;
+ }
+
/**
* Creates an FtpURLConnection from a URL.
*
@@ -168,7 +185,7 @@ public class FtpURLConnection extends URLConnection {
* Same as FtpURLconnection(URL) with a per connection proxy specified
*/
FtpURLConnection(URL url, Proxy p) {
- super(url);
+ super(checkURL(url));
instProxy = p;
host = url.getHost();
port = url.getPort();
diff --git a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
index 4c5ec78fca25ec82bf0b93d2e8bcb7a86897e666..6adc9f65b7fd41ecc807a395f5be1707bdbeb028 100644
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
+++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,6 +66,7 @@ import java.util.HashSet;
import java.util.HashMap;
import java.util.Set;
import sun.net.*;
+import sun.net.util.IPAddressUtil;
import sun.net.www.*;
import sun.net.www.http.HttpClient;
import sun.net.www.http.PosterOutputStream;
@@ -850,8 +851,13 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
throw new MalformedURLException("Illegal character in URL");
}
}
+ String s = IPAddressUtil.checkAuthority(u);
+ if (s != null) {
+ throw new MalformedURLException(s);
+ }
return u;
}
+
protected HttpURLConnection(URL u, Proxy p, Handler handler)
throws IOException {
super(checkURL(u));
diff --git a/src/share/classes/sun/net/www/protocol/https/HttpsURLConnectionImpl.java b/src/share/classes/sun/net/www/protocol/https/HttpsURLConnectionImpl.java
index e43a36310ab1d2f48349a1090d0f8210ee2bca80..0186e2472573607a6678d3b9a23443170357ec9b 100644
--- a/src/share/classes/sun/net/www/protocol/https/HttpsURLConnectionImpl.java
+++ b/src/share/classes/sun/net/www/protocol/https/HttpsURLConnectionImpl.java
@@ -45,6 +45,7 @@ import java.security.Permission;
import java.security.Principal;
import java.util.Map;
import java.util.List;
+import sun.net.util.IPAddressUtil;
import sun.net.www.http.HttpClient;
/**
@@ -86,6 +87,10 @@ public class HttpsURLConnectionImpl
throw new MalformedURLException("Illegal character in URL");
}
}
+ String s = IPAddressUtil.checkAuthority(u);
+ if (s != null) {
+ throw new MalformedURLException(s);
+ }
return u;
}
// For both copies of the file, uncomment one line and comment the other
@@ -333,7 +338,7 @@ public class HttpsURLConnectionImpl
* @param key the keyword by which the request is known
* (e.g., "accept").
* @param value the value associated with it.
- * @see #getRequestProperties(java.lang.String)
+ * @see #getRequestProperty(java.lang.String)
* @since 1.4
*/
public void addRequestProperty(String key, String value) {
diff --git a/src/share/classes/sun/security/provider/DigestBase.java b/src/share/classes/sun/security/provider/DigestBase.java
index c3ac4ac36f59ac016d3071557cf7f0de05719343..89b1d77f31bf5dab9d876b5b6b99500f1c4e6459 100644
--- a/src/share/classes/sun/security/provider/DigestBase.java
+++ b/src/share/classes/sun/security/provider/DigestBase.java
@@ -29,6 +29,7 @@ import java.security.MessageDigestSpi;
import java.security.DigestException;
import java.security.ProviderException;
import java.util.Arrays;
+import java.util.Objects;
/**
* Common base message digest implementation for the Sun provider.
@@ -137,12 +138,35 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable {
// compress complete blocks
private int implCompressMultiBlock(byte[] b, int ofs, int limit) {
+ implCompressMultiBlockCheck(b, ofs, limit);
+ return implCompressMultiBlock0(b, ofs, limit);
+ }
+
+ private int implCompressMultiBlock0(byte[] b, int ofs, int limit) {
for (; ofs <= limit; ofs += blockSize) {
implCompress(b, ofs);
}
return ofs;
}
+ private void implCompressMultiBlockCheck(byte[] b, int ofs, int limit) {
+ if (limit < 0) {
+ return; // not an error because implCompressMultiBlockImpl won't execute if limit < 0
+ // and an exception is thrown if ofs < 0.
+ }
+
+ Objects.requireNonNull(b);
+
+ if (ofs < 0 || ofs >= b.length) {
+ throw new ArrayIndexOutOfBoundsException(ofs);
+ }
+
+ int endIndex = (limit / blockSize) * blockSize + blockSize - 1;
+ if (endIndex >= b.length) {
+ throw new ArrayIndexOutOfBoundsException(endIndex);
+ }
+ }
+
// reset this object. See JCA doc.
protected final void engineReset() {
if (bytesProcessed == 0) {
diff --git a/src/share/classes/sun/security/provider/SHA.java b/src/share/classes/sun/security/provider/SHA.java
index 24dc0b2897f60ef79cd4bd9ecc3aa142a0b450fc..dfa477adf2d7afd8af6829f84672eebe5996e268 100644
--- a/src/share/classes/sun/security/provider/SHA.java
+++ b/src/share/classes/sun/security/provider/SHA.java
@@ -27,6 +27,8 @@ package sun.security.provider;
import java.util.Arrays;
+import java.util.Objects;
+
import static sun.security.provider.ByteArrayAccess.*;
/**
@@ -123,8 +125,26 @@ public final class SHA extends DigestBase {
* "old" NIST Secure Hash Algorithm.
*/
void implCompress(byte[] buf, int ofs) {
+ implCompressCheck(buf, ofs);
+ implCompress0(buf, ofs);
+ }
+
+ private void implCompressCheck(byte[] buf, int ofs) {
+ Objects.requireNonNull(buf);
+
+ // The checks performed by the method 'b2iBig64'
+ // are sufficient for the case when the method
+ // 'implCompressImpl' is replaced with a compiler
+ // intrinsic.
b2iBig64(buf, ofs, W);
+ }
+ // The method 'implCompressImpl seems not to use its parameters.
+ // The method can, however, be replaced with a compiler intrinsic
+ // that operates directly on the array 'buf' (starting from
+ // offset 'ofs') and not on array 'W', therefore 'buf' and 'ofs'
+ // must be passed as parameter to the method.
+ private void implCompress0(byte[] buf, int ofs) {
// The first 16 ints have the byte stream, compute the rest of
// the buffer
for (int t = 16; t <= 79; t++) {
diff --git a/src/share/classes/sun/security/provider/SHA2.java b/src/share/classes/sun/security/provider/SHA2.java
index 6f34c8d55dfc09b0dab5fc0e58afa1a8c9e40d8e..25f13d0736477f42dfbeba755e3e902f30d91af4 100644
--- a/src/share/classes/sun/security/provider/SHA2.java
+++ b/src/share/classes/sun/security/provider/SHA2.java
@@ -27,6 +27,8 @@ package sun.security.provider;
import java.util.Arrays;
+import java.util.Objects;
+
import static sun.security.provider.ByteArrayAccess.*;
/**
@@ -193,8 +195,26 @@ abstract class SHA2 extends DigestBase {
* Process the current block to update the state variable state.
*/
void implCompress(byte[] buf, int ofs) {
+ implCompressCheck(buf, ofs);
+ implCompress0(buf, ofs);
+ }
+
+ private void implCompressCheck(byte[] buf, int ofs) {
+ Objects.requireNonNull(buf);
+
+ // The checks performed by the method 'b2iBig64'
+ // are sufficient for the case when the method
+ // 'implCompressImpl' is replaced with a compiler
+ // intrinsic.
b2iBig64(buf, ofs, W);
+ }
+ // The method 'implCompressImpl' seems not to use its parameters.
+ // The method can, however, be replaced with a compiler intrinsic
+ // that operates directly on the array 'buf' (starting from
+ // offset 'ofs') and not on array 'W', therefore 'buf' and 'ofs'
+ // must be passed as parameter to the method.
+ private void implCompress0(byte[] buf, int ofs) {
// The first 16 ints are from the byte stream, compute the rest of
// the W[]'s
for (int t = 16; t < ITERATION; t++) {
diff --git a/src/share/classes/sun/security/provider/SHA5.java b/src/share/classes/sun/security/provider/SHA5.java
index 90c12526d8e34fa61fe51125303cef043a56030e..ceba1fc2b2dd6b1b0c1ae8a71745b8c2cd4e0dc2 100644
--- a/src/share/classes/sun/security/provider/SHA5.java
+++ b/src/share/classes/sun/security/provider/SHA5.java
@@ -26,6 +26,7 @@
package sun.security.provider;
import java.util.Arrays;
+import java.util.Objects;
import static sun.security.provider.ByteArrayAccess.*;
@@ -209,8 +210,26 @@ abstract class SHA5 extends DigestBase {
* "old" NIST Secure Hash Algorithm.
*/
final void implCompress(byte[] buf, int ofs) {
+ implCompressCheck(buf, ofs);
+ implCompress0(buf, ofs);
+ }
+
+ private void implCompressCheck(byte[] buf, int ofs) {
+ Objects.requireNonNull(buf);
+
+ // The checks performed by the method 'b2iBig128'
+ // are sufficient for the case when the method
+ // 'implCompressImpl' is replaced with a compiler
+ // intrinsic.
b2lBig128(buf, ofs, W);
+ }
+ // The method 'implCompressImpl' seems not to use its parameters.
+ // The method can, however, be replaced with a compiler intrinsic
+ // that operates directly on the array 'buf' (starting from
+ // offset 'ofs') and not on array 'W', therefore 'buf' and 'ofs'
+ // must be passed as parameter to the method.
+ private final void implCompress0(byte[] buf, int ofs) {
// The first 16 longs are from the byte stream, compute the rest of
// the W[]'s
for (int t = 16; t < ITERATION; t++) {
diff --git a/src/share/classes/sun/security/ssl/SSLContextImpl.java b/src/share/classes/sun/security/ssl/SSLContextImpl.java
index 9659d258b1c5ea1960994782f256555d719f983d..4753b02fffa18ba5ad42c28323b2164d893d752b 100644
--- a/src/share/classes/sun/security/ssl/SSLContextImpl.java
+++ b/src/share/classes/sun/security/ssl/SSLContextImpl.java
@@ -1114,8 +1114,9 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
checkAdditionalTrust(chain, authType, engine, false);
}
- private void checkAdditionalTrust(X509Certificate[] chain, String authType,
- Socket socket, boolean isClient) throws CertificateException {
+ private void checkAdditionalTrust(X509Certificate[] chain,
+ String authType, Socket socket,
+ boolean checkClientTrusted) throws CertificateException {
if (socket != null && socket.isConnected() &&
socket instanceof SSLSocket) {
@@ -1129,9 +1130,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
String identityAlg = sslSocket.getSSLParameters().
getEndpointIdentificationAlgorithm();
if (identityAlg != null && identityAlg.length() != 0) {
- String hostname = session.getPeerHost();
- X509TrustManagerImpl.checkIdentity(
- hostname, chain[0], identityAlg);
+ X509TrustManagerImpl.checkIdentity(session, chain,
+ identityAlg, checkClientTrusted);
}
// try the best to check the algorithm constraints
@@ -1155,12 +1155,13 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
constraints = new SSLAlgorithmConstraints(sslSocket, true);
}
- checkAlgorithmConstraints(chain, constraints, isClient);
+ checkAlgorithmConstraints(chain, constraints, checkClientTrusted);
}
}
- private void checkAdditionalTrust(X509Certificate[] chain, String authType,
- SSLEngine engine, boolean isClient) throws CertificateException {
+ private void checkAdditionalTrust(X509Certificate[] chain,
+ String authType, SSLEngine engine,
+ boolean checkClientTrusted) throws CertificateException {
if (engine != null) {
SSLSession session = engine.getHandshakeSession();
if (session == null) {
@@ -1171,9 +1172,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
String identityAlg = engine.getSSLParameters().
getEndpointIdentificationAlgorithm();
if (identityAlg != null && identityAlg.length() != 0) {
- String hostname = session.getPeerHost();
- X509TrustManagerImpl.checkIdentity(
- hostname, chain[0], identityAlg);
+ X509TrustManagerImpl.checkIdentity(session, chain,
+ identityAlg, checkClientTrusted);
}
// try the best to check the algorithm constraints
@@ -1197,12 +1197,13 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
constraints = new SSLAlgorithmConstraints(engine, true);
}
- checkAlgorithmConstraints(chain, constraints, isClient);
+ checkAlgorithmConstraints(chain, constraints, checkClientTrusted);
}
}
private void checkAlgorithmConstraints(X509Certificate[] chain,
- AlgorithmConstraints constraints, boolean isClient) throws CertificateException {
+ AlgorithmConstraints constraints,
+ boolean checkClientTrusted) throws CertificateException {
try {
// Does the certificate chain end with a trusted certificate?
@@ -1222,7 +1223,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
if (checkedLength >= 0) {
AlgorithmChecker checker =
new AlgorithmChecker(constraints, null,
- (isClient ? Validator.VAR_TLS_CLIENT : Validator.VAR_TLS_SERVER));
+ (checkClientTrusted ? Validator.VAR_TLS_CLIENT :
+ Validator.VAR_TLS_SERVER));
checker.init(false);
for (int i = checkedLength; i >= 0; i--) {
Certificate cert = chain[i];
diff --git a/src/share/classes/sun/security/ssl/X509TrustManagerImpl.java b/src/share/classes/sun/security/ssl/X509TrustManagerImpl.java
index 5a829a55066b274b5b5ceaf6a27f4b34e40a6d93..19801b16ec31c6b7d0e871ce9c6b16b749f4d29a 100644
--- a/src/share/classes/sun/security/ssl/X509TrustManagerImpl.java
+++ b/src/share/classes/sun/security/ssl/X509TrustManagerImpl.java
@@ -145,7 +145,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
}
private Validator checkTrustedInit(X509Certificate[] chain,
- String authType, boolean isClient) {
+ String authType, boolean checkClientTrusted) {
if (chain == null || chain.length == 0) {
throw new IllegalArgumentException(
"null or zero-length certificate chain");
@@ -157,7 +157,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
}
Validator v = null;
- if (isClient) {
+ if (checkClientTrusted) {
v = clientValidator;
if (v == null) {
synchronized (this) {
@@ -187,9 +187,10 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
}
- private void checkTrusted(X509Certificate[] chain, String authType,
- Socket socket, boolean isClient) throws CertificateException {
- Validator v = checkTrustedInit(chain, authType, isClient);
+ private void checkTrusted(X509Certificate[] chain,
+ String authType, Socket socket,
+ boolean checkClientTrusted) throws CertificateException {
+ Validator v = checkTrustedInit(chain, authType, checkClientTrusted);
AlgorithmConstraints constraints = null;
if ((socket != null) && socket.isConnected() &&
@@ -205,8 +206,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
String identityAlg = sslSocket.getSSLParameters().
getEndpointIdentificationAlgorithm();
if (identityAlg != null && identityAlg.length() != 0) {
- checkIdentity(session, chain[0], identityAlg, isClient,
- getRequestedServerNames(socket));
+ checkIdentity(session, chain, identityAlg, checkClientTrusted);
}
// create the algorithm constraints
@@ -231,7 +231,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
}
X509Certificate[] trustedChain = null;
- if (isClient) {
+ if (checkClientTrusted) {
trustedChain = validate(v, chain, constraints, null);
} else {
trustedChain = validate(v, chain, constraints, authType);
@@ -242,9 +242,10 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
}
}
- private void checkTrusted(X509Certificate[] chain, String authType,
- SSLEngine engine, boolean isClient) throws CertificateException {
- Validator v = checkTrustedInit(chain, authType, isClient);
+ private void checkTrusted(X509Certificate[] chain,
+ String authType, SSLEngine engine,
+ boolean checkClientTrusted) throws CertificateException {
+ Validator v = checkTrustedInit(chain, authType, checkClientTrusted);
AlgorithmConstraints constraints = null;
if (engine != null) {
@@ -257,8 +258,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
String identityAlg = engine.getSSLParameters().
getEndpointIdentificationAlgorithm();
if (identityAlg != null && identityAlg.length() != 0) {
- checkIdentity(session, chain[0], identityAlg, isClient,
- getRequestedServerNames(engine));
+ checkIdentity(session, chain, identityAlg, checkClientTrusted);
}
// create the algorithm constraints
@@ -283,7 +283,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
}
X509Certificate[] trustedChain = null;
- if (isClient) {
+ if (checkClientTrusted) {
trustedChain = validate(v, chain, constraints, null);
} else {
trustedChain = validate(v, chain, constraints, authType);
@@ -373,13 +373,8 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
if (socket != null && socket.isConnected() &&
socket instanceof SSLSocket) {
- SSLSocket sslSocket = (SSLSocket)socket;
- SSLSession session = sslSocket.getHandshakeSession();
-
- if (session != null && (session instanceof ExtendedSSLSession)) {
- ExtendedSSLSession extSession = (ExtendedSSLSession)session;
- return extSession.getRequestedServerNames();
- }
+ return getRequestedServerNames(
+ ((SSLSocket)socket).getHandshakeSession());
}
return Collections.emptyList();
@@ -388,12 +383,16 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
// Also used by X509KeyManagerImpl
static List getRequestedServerNames(SSLEngine engine) {
if (engine != null) {
- SSLSession session = engine.getHandshakeSession();
+ return getRequestedServerNames(engine.getHandshakeSession());
+ }
- if (session != null && (session instanceof ExtendedSSLSession)) {
- ExtendedSSLSession extSession = (ExtendedSSLSession)session;
- return extSession.getRequestedServerNames();
- }
+ return Collections.emptyList();
+ }
+
+ private static List getRequestedServerNames(
+ SSLSession session) {
+ if (session != null && (session instanceof ExtendedSSLSession)) {
+ return ((ExtendedSSLSession)session).getRequestedServerNames();
}
return Collections.emptyList();
@@ -414,22 +413,23 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
* the identity checking aginst the server_name extension if present, and
* may failove to peer host checking.
*/
- private static void checkIdentity(SSLSession session,
- X509Certificate cert,
+ static void checkIdentity(SSLSession session,
+ X509Certificate [] trustedChain,
String algorithm,
- boolean isClient,
- List sniNames) throws CertificateException {
+ boolean checkClientTrusted) throws CertificateException {
boolean identifiable = false;
String peerHost = session.getPeerHost();
- if (isClient) {
- String hostname = getHostNameInSNI(sniNames);
- if (hostname != null) {
+ if (!checkClientTrusted) {
+ List sniNames = getRequestedServerNames(session);
+ String sniHostName = getHostNameInSNI(sniNames);
+ if (sniHostName != null) {
try {
- checkIdentity(hostname, cert, algorithm);
+ checkIdentity(sniHostName,
+ trustedChain[0], algorithm);
identifiable = true;
} catch (CertificateException ce) {
- if (hostname.equalsIgnoreCase(peerHost)) {
+ if (sniHostName.equalsIgnoreCase(peerHost)) {
throw ce;
}
@@ -439,7 +439,8 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
}
if (!identifiable) {
- checkIdentity(peerHost, cert, algorithm);
+ checkIdentity(peerHost,
+ trustedChain[0], algorithm);
}
}
diff --git a/src/share/classes/sun/security/util/ArrayUtil.java b/src/share/classes/sun/security/util/ArrayUtil.java
index 5e5fc0aa52e29b6abc30295116f48958e48752a8..331c10079cb91badc089b1bf567b40893e018890 100644
--- a/src/share/classes/sun/security/util/ArrayUtil.java
+++ b/src/share/classes/sun/security/util/ArrayUtil.java
@@ -25,12 +25,34 @@
package sun.security.util;
+import java.util.List;
+import java.util.function.BiFunction;
+import java.security.*;
+import jdk.internal.util.Preconditions;
+
+
/**
* This class holds the various utility methods for array range checks.
*/
public final class ArrayUtil {
+ private static final BiFunction,
+ ArrayIndexOutOfBoundsException> AIOOBE_SUPPLIER =
+ Preconditions.outOfBoundsExceptionFormatter
+ (ArrayIndexOutOfBoundsException::new);
+
+ public static void blockSizeCheck(int len, int blockSize) {
+ if ((len % blockSize) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
+ }
+
+ public static void nullAndBoundsCheck(byte[] array, int offset, int len) {
+ // NPE is thrown when array is null
+ Preconditions.checkFromIndexSize(offset, len, array.length, AIOOBE_SUPPLIER);
+ }
+
private static void swap(byte[] arr, int i, int j) {
byte tmp = arr[i];
arr[i] = arr[j];
@@ -48,4 +70,3 @@ public final class ArrayUtil {
}
}
}
-
diff --git a/src/share/classes/sun/security/util/DerIndefLenConverter.java b/src/share/classes/sun/security/util/DerIndefLenConverter.java
index cbd5ecc00e705b5fa2d745daa4f67589d6b9e6bb..9eb44862cbc5fb8f346d8e5b909afea6990f441a 100644
--- a/src/share/classes/sun/security/util/DerIndefLenConverter.java
+++ b/src/share/classes/sun/security/util/DerIndefLenConverter.java
@@ -92,37 +92,41 @@ class DerIndefLenConverter {
private void parseTag() throws IOException {
if (dataPos == dataSize)
return;
- if (isEOC(data[dataPos]) && (data[dataPos + 1] == 0)) {
- int numOfEncapsulatedLenBytes = 0;
- Object elem = null;
- int index;
- for (index = ndefsList.size()-1; index >= 0; index--) {
- // Determine the first element in the vector that does not
- // have a matching EOC
- elem = ndefsList.get(index);
- if (elem instanceof Integer) {
- break;
- } else {
- numOfEncapsulatedLenBytes += ((byte[])elem).length - 3;
+ try {
+ if (isEOC(data[dataPos]) && (data[dataPos + 1] == 0)) {
+ int numOfEncapsulatedLenBytes = 0;
+ Object elem = null;
+ int index;
+ for (index = ndefsList.size()-1; index >= 0; index--) {
+ // Determine the first element in the vector that does not
+ // have a matching EOC
+ elem = ndefsList.get(index);
+ if (elem instanceof Integer) {
+ break;
+ } else {
+ numOfEncapsulatedLenBytes += ((byte[])elem).length - 3;
+ }
}
+ if (index < 0) {
+ throw new IOException("EOC does not have matching " +
+ "indefinite-length tag");
+ }
+ int sectionLen = dataPos - ((Integer)elem).intValue() +
+ numOfEncapsulatedLenBytes;
+ byte[] sectionLenBytes = getLengthBytes(sectionLen);
+ ndefsList.set(index, sectionLenBytes);
+ unresolved--;
+
+ // Add the number of bytes required to represent this section
+ // to the total number of length bytes,
+ // and subtract the indefinite-length tag (1 byte) and
+ // EOC bytes (2 bytes) for this section
+ numOfTotalLenBytes += (sectionLenBytes.length - 3);
}
- if (index < 0) {
- throw new IOException("EOC does not have matching " +
- "indefinite-length tag");
- }
- int sectionLen = dataPos - ((Integer)elem).intValue() +
- numOfEncapsulatedLenBytes;
- byte[] sectionLenBytes = getLengthBytes(sectionLen);
- ndefsList.set(index, sectionLenBytes);
- unresolved--;
-
- // Add the number of bytes required to represent this section
- // to the total number of length bytes,
- // and subtract the indefinite-length tag (1 byte) and
- // EOC bytes (2 bytes) for this section
- numOfTotalLenBytes += (sectionLenBytes.length - 3);
+ dataPos++;
+ } catch (IndexOutOfBoundsException iobe) {
+ throw new IOException(iobe);
}
- dataPos++;
}
/**
diff --git a/src/share/classes/sun/security/util/HostnameChecker.java b/src/share/classes/sun/security/util/HostnameChecker.java
index 1b30cf53292e966bafe01d09f043f245ad4fde2a..89712ddd9990fa17211fc5393f6aa1569fab2fe3 100644
--- a/src/share/classes/sun/security/util/HostnameChecker.java
+++ b/src/share/classes/sun/security/util/HostnameChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -262,18 +262,17 @@ public class HostnameChecker {
* The matching is performed as per RFC 2818 rules for TLS and
* RFC 2830 rules for LDAP.
*
- * The name parameter should represent a DNS name.
- * The template parameter
- * may contain the wildcard character *
+ * The name parameter should represent a DNS name. The
+ * template parameter may contain the wildcard character '*'.
*/
private boolean isMatched(String name, String template) {
// check the validity of the domain name template.
try {
- // Replacing wildcard character '*' with 'x' so as to check
+ // Replacing wildcard character '*' with 'z' so as to check
// the domain name template validity.
//
// Using the checking implemented in SNIHostName
- SNIHostName sni = new SNIHostName(template.replace('*', 'x'));
+ SNIHostName sni = new SNIHostName(template.replace('*', 'z'));
} catch (IllegalArgumentException iae) {
// It would be nice to add debug log if not matching.
return false;
diff --git a/src/share/native/sun/awt/libpng/png.c b/src/share/native/sun/awt/libpng/png.c
index 1a44c9c8cfc89218f7033bda47a52e4d671d61e4..a471c76d06021056c80eafa38f4dc89d833603e0 100644
--- a/src/share/native/sun/awt/libpng/png.c
+++ b/src/share/native/sun/awt/libpng/png.c
@@ -4622,8 +4622,7 @@ png_image_free(png_imagep image)
if (image != NULL && image->opaque != NULL &&
image->opaque->error_buf == NULL)
{
- /* Ignore errors here: */
- (void)png_safe_execute(image, png_image_free_function, image);
+ png_image_free_function(image);
image->opaque = NULL;
}
}
diff --git a/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp b/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp
index f296e89d3d59de7b7233b54a582f900e67e1250b..b27d4ee5010c9970dd2b3e42d44f097530ac2cda 100644
--- a/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp
+++ b/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp
@@ -50,7 +50,13 @@ le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo
+ arrayRef(base, success, alternateSetTableOffsetArray, altSetCount);
+ if (!LE_SUCCESS(success)) return 0;
+
+ Offset alternateSetTableOffset = SWAPW(arrayRef.getObject(coverageIndex, success));
+ if (!LE_SUCCESS(success)) return 0;
+
const LEReferenceTo alternateSetTable(base, success,
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
if (!LE_SUCCESS(success)) return 0;
diff --git a/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp b/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp
index 086da91629e583401f48c060f36e088b9a51fe53..f8081a9c22324ed037aa62c1c6b7bb8572f0c80f 100644
--- a/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp
+++ b/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp
@@ -80,6 +80,9 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
// FIXME: We probably don't want to find a base glyph before a previous ligature...
GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/));
LEGlyphID baseGlyph = findBaseGlyph(&baseIterator);
+ if (baseGlyph == 0xFFFF) {
+ return 0;
+ }
le_int32 baseCoverage = getBaseCoverage(base, (LEGlyphID) baseGlyph, success);
LEReferenceTo baseArray(base, success, (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset)));
if(LE_FAILURE(success)) return 0;
diff --git a/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp b/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp
index 2515b8afb5afcabb2009d4cf490f7902db49c0f6..e70f35c50e5bea7d7a2bc038b73a6d3531b9b4f9 100644
--- a/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp
+++ b/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp
@@ -81,6 +81,9 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
// FIXME: we probably don't want to find a ligature before a previous base glyph...
GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/));
LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator);
+ if (ligatureGlyph == 0xFFFF) {
+ return 0;
+ }
le_int32 ligatureCoverage = getBaseCoverage(base, (LEGlyphID) ligatureGlyph, success);
LEReferenceTo ligatureArray(base, success, SWAPW(baseArrayOffset));
if (LE_FAILURE(success)) { return 0; }
diff --git a/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp b/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp
index 4ed835453af14493d0eb1e946d4177fa1288ce80..0e16a2fced2c808c255b0176c434a3e160291073 100644
--- a/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp
+++ b/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp
@@ -81,6 +81,9 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
GlyphIterator mark2Iterator(*glyphIterator);
LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator);
+ if (mark2Glyph == 0xFFFF) {
+ return 0;
+ }
le_int32 mark2Coverage = getBaseCoverage(base, (LEGlyphID) mark2Glyph, success);
LEReferenceTo mark2Array(base, success, (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset)));
if(LE_FAILURE(success)) return 0;
diff --git a/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp b/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp
index b4c9122c5e24fa5a69da895fb7bf976cc1ea289f..a02894954f3dd219c75ef75d387259bbe777f4aa 100644
--- a/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp
+++ b/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp
@@ -543,7 +543,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
yAdjust += yKerning;
#endif
- for (le_int32 base = i; base >= 0; base = adjustments->getBaseOffset(base)) {
+ for (le_int32 base = i; base >= 0 && base < glyphCount; base = adjustments->getBaseOffset(base)) {
xPlacement += adjustments->getXPlacement(base);
yPlacement += adjustments->getYPlacement(base);
}
diff --git a/src/windows/classes/sun/net/www/protocol/file/Handler.java b/src/windows/classes/sun/net/www/protocol/file/Handler.java
index 8a5531268decc27fa367a1390feb417dde878b33..7a331a0c5ece6a2afb521f9504013876feec8a26 100644
--- a/src/windows/classes/sun/net/www/protocol/file/Handler.java
+++ b/src/windows/classes/sun/net/www/protocol/file/Handler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -95,7 +95,7 @@ public class Handler extends URLStreamHandler {
path = "\\\\" + host + path;
File f = new File(path);
if (f.exists()) {
- return createFileURLConnection(url, f);
+ return new UNCFileURLConnection(url, f, path);
}
/*
diff --git a/src/windows/classes/sun/net/www/protocol/file/UNCFileURLConnection.java b/src/windows/classes/sun/net/www/protocol/file/UNCFileURLConnection.java
new file mode 100644
index 0000000000000000000000000000000000000000..c36b84aa4dcface26605d43d8e885ece6752f435
--- /dev/null
+++ b/src/windows/classes/sun/net/www/protocol/file/UNCFileURLConnection.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.net.www.protocol.file;
+
+import java.io.File;
+import java.io.FilePermission;
+import java.net.URL;
+import java.security.Permission;
+
+final class UNCFileURLConnection extends FileURLConnection {
+
+ private final String effectivePath;
+ private volatile Permission permission;
+
+ UNCFileURLConnection(URL u, File file, String effectivePath) {
+ super(u, file);
+ this.effectivePath = effectivePath;
+ }
+
+ @Override
+ public Permission getPermission() {
+ Permission perm = permission;
+ if (perm == null) {
+ permission = perm = new FilePermission(effectivePath, "read");
+ }
+ return perm;
+ }
+}
+
diff --git a/src/windows/native/sun/security/mscapi/security.cpp b/src/windows/native/sun/security/mscapi/security.cpp
index 7012a35ccd57d6e11363ee8990ee0b318c9345ec..12c408e8ee3a13394d9db4e079c8e6048a931520 100644
--- a/src/windows/native/sun/security/mscapi/security.cpp
+++ b/src/windows/native/sun/security/mscapi/security.cpp
@@ -202,14 +202,17 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_PRNG_generateSeed
}
/*
- * If length is negative then use the supplied seed to re-seed the
- * generator and return null.
+ * If length is negative and a seed is supplied, use it to re-seed the
+ * generator. Return null whether a seed is supplied or not.
* If length is non-zero then generate a new seed according to the
* requested length and return the new seed.
* If length is zero then overwrite the supplied seed with a new
* seed of the same length and return the seed.
*/
if (length < 0) {
+ if (seed == NULL) {
+ __leave;
+ }
length = env->GetArrayLength(seed);
if ((reseedBytes = env->GetByteArrayElements(seed, 0)) == NULL) {
__leave;
diff --git a/test/java/util/Objects/CheckIndex.java b/test/java/util/Objects/CheckIndex.java
new file mode 100644
index 0000000000000000000000000000000000000000..4fe72e5ce37e3730fbb4fd5ef8a6bf8beb7b1918
--- /dev/null
+++ b/test/java/util/Objects/CheckIndex.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2015, 2016 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @summary Objects.checkIndex/jdk.internal.util.Preconditions.checkIndex tests
+ * @run testng CheckIndex
+ * @bug 8135248 8142493 8155794
+ * @modules java.base/jdk.internal.util
+ */
+
+import jdk.internal.util.Preconditions;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.IntSupplier;
+
+import static org.testng.Assert.*;
+
+public class CheckIndex {
+
+ static class AssertingOutOfBoundsException extends RuntimeException {
+ public AssertingOutOfBoundsException(String message) {
+ super(message);
+ }
+ }
+
+ static BiFunction, AssertingOutOfBoundsException> assertingOutOfBounds(
+ String message, String expCheckKind, Integer... expArgs) {
+ return (checkKind, args) -> {
+ assertEquals(checkKind, expCheckKind);
+ assertEquals(args, Collections.unmodifiableList(Arrays.asList(expArgs)));
+ try {
+ args.clear();
+ fail("Out of bounds List argument should be unmodifiable");
+ } catch (Exception e) {
+ }
+ return new AssertingOutOfBoundsException(message);
+ };
+ }
+
+ static BiFunction, AssertingOutOfBoundsException> assertingOutOfBoundsReturnNull(
+ String expCheckKind, Integer... expArgs) {
+ return (checkKind, args) -> {
+ assertEquals(checkKind, expCheckKind);
+ assertEquals(args, Collections.unmodifiableList(Arrays.asList(expArgs)));
+ return null;
+ };
+ }
+
+ static final int[] VALUES = {0, 1, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, -1, Integer.MIN_VALUE + 1, Integer.MIN_VALUE};
+
+ @DataProvider
+ static Object[][] checkIndexProvider() {
+ List