提交 b4d54f34 编写于 作者: A andrew

Merge

...@@ -997,3 +997,6 @@ e880f2d161bf23a09f8c1a19861d7df7d2ed126f jdk8u222-b01 ...@@ -997,3 +997,6 @@ e880f2d161bf23a09f8c1a19861d7df7d2ed126f jdk8u222-b01
c7a97c9b7e5932d651eda37c8a907311818491d7 jdk8u222-b07 c7a97c9b7e5932d651eda37c8a907311818491d7 jdk8u222-b07
0bb89d93d4d7da64d408a9888df21085e7bfb291 jdk8u222-b08 0bb89d93d4d7da64d408a9888df21085e7bfb291 jdk8u222-b08
887c8314411dd461ec4b1e14cd6368ed3d9a7a3b jdk8u232-b00 887c8314411dd461ec4b1e14cd6368ed3d9a7a3b jdk8u232-b00
0da125166b2bd35aac0d6222ba44535730e2713f jdk8u222-b09
2a9bea6e5e03a53469abdcd2da268a312cc7b5b8 jdk8u222-b10
2a9bea6e5e03a53469abdcd2da268a312cc7b5b8 jdk8u222-ga
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -102,7 +102,8 @@ NSDictionary *realmConfigsForRealms(SCDynamicStoreRef store, NSArray *realms) { ...@@ -102,7 +102,8 @@ NSDictionary *realmConfigsForRealms(SCDynamicStoreRef store, NSArray *realms) {
for (NSString *realm in realms) { for (NSString *realm in realms) {
CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]); 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; return nil;
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -184,7 +184,7 @@ SplashInitPlatform(Splash * splash) { ...@@ -184,7 +184,7 @@ SplashInitPlatform(Splash * splash) {
splash->maskRequired = 0; splash->maskRequired = 0;
//TODO: the following is too much of a hack but should work in 90% cases. //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 // besides we don't use device-dependant drawing, so probably
// that's very fine indeed // that's very fine indeed
...@@ -251,9 +251,11 @@ void ...@@ -251,9 +251,11 @@ void
SplashRedrawWindow(Splash * splash) { SplashRedrawWindow(Splash * splash) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SplashUpdateScreenData(splash);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
// drop the reference to the old view and image
[splash->window setContentView: nil];
SplashUpdateScreenData(splash);
// NSDeviceRGBColorSpace vs. NSCalibratedRGBColorSpace ? // NSDeviceRGBColorSpace vs. NSCalibratedRGBColorSpace ?
NSBitmapImageRep * rep = [[NSBitmapImageRep alloc] NSBitmapImageRep * rep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: (unsigned char**)&splash->screenData initWithBitmapDataPlanes: (unsigned char**)&splash->screenData
...@@ -281,7 +283,7 @@ SplashRedrawWindow(Splash * splash) { ...@@ -281,7 +283,7 @@ SplashRedrawWindow(Splash * splash) {
size.height /= scaleFactor; size.height /= scaleFactor;
[image setSize: size]; [image setSize: size];
} }
NSImageView * view = [[NSImageView alloc] init]; NSImageView * view = [[NSImageView alloc] init];
[view setImage: image]; [view setImage: image];
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -346,7 +346,15 @@ final class AESCrypt extends SymmetricCipher implements AESConstants ...@@ -346,7 +346,15 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
* Encrypt exactly one block of plaintext. * Encrypt exactly one block of plaintext.
*/ */
void encryptBlock(byte[] in, int inOffset, 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 keyOffset = 0;
int t0 = ((in[inOffset++] ) << 24 | int t0 = ((in[inOffset++] ) << 24 |
...@@ -412,12 +420,19 @@ final class AESCrypt extends SymmetricCipher implements AESConstants ...@@ -412,12 +420,19 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt )); out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt ));
} }
/** /**
* Decrypt exactly one block of plaintext. * Decrypt exactly one block of plaintext.
*/ */
void decryptBlock(byte[] in, int inOffset, 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 keyOffset = 4;
int t0 = ((in[inOffset++] ) << 24 | int t0 = ((in[inOffset++] ) << 24 |
...@@ -572,7 +587,6 @@ final class AESCrypt extends SymmetricCipher implements AESConstants ...@@ -572,7 +587,6 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 )); out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 ));
} }
/** /**
* Expand a user-supplied key material into a session key. * Expand a user-supplied key material into a session key.
* *
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,7 +27,9 @@ package com.sun.crypto.provider; ...@@ -27,7 +27,9 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.ProviderException; import java.security.ProviderException;
import java.util.Objects;
import sun.security.util.ArrayUtil;
/** /**
* This class represents ciphers in cipher block chaining (CBC) mode. * This class represents ciphers in cipher block chaining (CBC) mode.
...@@ -138,18 +140,24 @@ class CipherBlockChaining extends FeedbackCipher { ...@@ -138,18 +140,24 @@ class CipherBlockChaining extends FeedbackCipher {
* @return the length of the encrypted data * @return the length of the encrypted data
*/ */
int encrypt(byte[] plain, int plainOffset, int plainLen, int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) byte[] cipher, int cipherOffset) {
{
if (plainLen <= 0) { if (plainLen <= 0) {
return plainLen; return plainLen;
} }
if ((plainLen % blockSize) != 0) { ArrayUtil.blockSizeCheck(plainLen, blockSize);
throw new ProviderException("Internal error in input buffering"); 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; int endIndex = plainOffset + plainLen;
for (; plainOffset < endIndex; for (; plainOffset < endIndex;
plainOffset+=blockSize, cipherOffset += blockSize) { plainOffset += blockSize, cipherOffset += blockSize) {
for (int i = 0; i < blockSize; i++) { for (int i = 0; i < blockSize; i++) {
k[i] = (byte)(plain[i + plainOffset] ^ r[i]); k[i] = (byte)(plain[i + plainOffset] ^ r[i]);
} }
...@@ -182,14 +190,19 @@ class CipherBlockChaining extends FeedbackCipher { ...@@ -182,14 +190,19 @@ class CipherBlockChaining extends FeedbackCipher {
* @return the length of the decrypted data * @return the length of the decrypted data
*/ */
int decrypt(byte[] cipher, int cipherOffset, int cipherLen, int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) byte[] plain, int plainOffset) {
{
if (cipherLen <= 0) { if (cipherLen <= 0) {
return cipherLen; return cipherLen;
} }
if ((cipherLen % blockSize) != 0) { ArrayUtil.blockSizeCheck(cipherLen, blockSize);
throw new ProviderException("Internal error in input buffering"); 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; int endIndex = cipherOffset + cipherLen;
for (; cipherOffset < endIndex; for (; cipherOffset < endIndex;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,6 +27,7 @@ package com.sun.crypto.provider; ...@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.ProviderException; import java.security.ProviderException;
import sun.security.util.ArrayUtil;
/** /**
* This class represents ciphers in cipher-feedback (CFB) mode. * This class represents ciphers in cipher-feedback (CFB) mode.
...@@ -149,9 +150,9 @@ final class CipherFeedback extends FeedbackCipher { ...@@ -149,9 +150,9 @@ final class CipherFeedback extends FeedbackCipher {
*/ */
int encrypt(byte[] plain, int plainOffset, int plainLen, int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) { byte[] cipher, int cipherOffset) {
if ((plainLen % numBytes) != 0) { ArrayUtil.blockSizeCheck(plainLen, numBytes);
throw new ProviderException("Internal error in input buffering"); ArrayUtil.nullAndBoundsCheck(plain, plainOffset, plainLen);
} ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, plainLen);
int nShift = blockSize - numBytes; int nShift = blockSize - numBytes;
int loopCount = plainLen / numBytes; int loopCount = plainLen / numBytes;
...@@ -225,9 +226,10 @@ final class CipherFeedback extends FeedbackCipher { ...@@ -225,9 +226,10 @@ final class CipherFeedback extends FeedbackCipher {
*/ */
int decrypt(byte[] cipher, int cipherOffset, int cipherLen, int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) { 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 nShift = blockSize - numBytes;
int loopCount = cipherLen / numBytes; int loopCount = cipherLen / numBytes;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,6 +27,7 @@ package com.sun.crypto.provider; ...@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import sun.security.util.ArrayUtil;
/** /**
* This class represents ciphers in counter (CTR) mode. * This class represents ciphers in counter (CTR) mode.
...@@ -173,6 +174,10 @@ final class CounterMode extends FeedbackCipher { ...@@ -173,6 +174,10 @@ final class CounterMode extends FeedbackCipher {
if (len == 0) { if (len == 0) {
return 0; return 0;
} }
ArrayUtil.nullAndBoundsCheck(in, inOff, len);
ArrayUtil.nullAndBoundsCheck(out, outOff, len);
int result = len; int result = len;
while (len-- > 0) { while (len-- > 0) {
if (used >= blockSize) { if (used >= blockSize) {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,6 +27,7 @@ package com.sun.crypto.provider; ...@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.ProviderException; import java.security.ProviderException;
import sun.security.util.ArrayUtil;
/** /**
* This class represents ciphers in electronic codebook (ECB) mode. * This class represents ciphers in electronic codebook (ECB) mode.
...@@ -112,9 +113,10 @@ final class ElectronicCodeBook extends FeedbackCipher { ...@@ -112,9 +113,10 @@ final class ElectronicCodeBook extends FeedbackCipher {
* @return the length of the encrypted data * @return the length of the encrypted data
*/ */
int encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { int encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
if ((len % blockSize) != 0) { ArrayUtil.blockSizeCheck(len, blockSize);
throw new ProviderException("Internal error in input buffering"); ArrayUtil.nullAndBoundsCheck(in, inOff, len);
} ArrayUtil.nullAndBoundsCheck(out, outOff, len);
for (int i = len; i >= blockSize; i -= blockSize) { for (int i = len; i >= blockSize; i -= blockSize) {
embeddedCipher.encryptBlock(in, inOff, out, outOff); embeddedCipher.encryptBlock(in, inOff, out, outOff);
inOff += blockSize; inOff += blockSize;
...@@ -141,9 +143,10 @@ final class ElectronicCodeBook extends FeedbackCipher { ...@@ -141,9 +143,10 @@ final class ElectronicCodeBook extends FeedbackCipher {
* @return the length of the decrypted data * @return the length of the decrypted data
*/ */
int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
if ((len % blockSize) != 0) { ArrayUtil.blockSizeCheck(len, blockSize);
throw new ProviderException("Internal error in input buffering"); ArrayUtil.nullAndBoundsCheck(in, inOff, len);
} ArrayUtil.nullAndBoundsCheck(out, outOff, len);
for (int i = len; i >= blockSize; i -= blockSize) { for (int i = len; i >= blockSize; i -= blockSize) {
embeddedCipher.decryptBlock(in, inOff, out, outOff); embeddedCipher.decryptBlock(in, inOff, out, outOff);
inOff += blockSize; inOff += blockSize;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,6 +30,8 @@ import java.io.*; ...@@ -30,6 +30,8 @@ import java.io.*;
import java.security.*; import java.security.*;
import javax.crypto.*; import javax.crypto.*;
import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE; import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
import sun.security.util.ArrayUtil;
/** /**
* This class represents ciphers in GaloisCounter (GCM) mode. * This class represents ciphers in GaloisCounter (GCM) mode.
...@@ -406,8 +408,8 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -406,8 +408,8 @@ final class GaloisCounterMode extends FeedbackCipher {
/** /**
* Performs encryption operation. * Performs encryption operation.
* *
* <p>The input plain text <code>in</code>, starting at <code>inOff</code> * <p>The input plain text <code>in</code>, starting at <code>inOfs</code>
* and ending at <code>(inOff + len - 1)</code>, is encrypted. The result * and ending at <code>(inOfs + len - 1)</code>, is encrypted. The result
* is stored in <code>out</code>, starting at <code>outOfs</code>. * is stored in <code>out</code>, starting at <code>outOfs</code>.
* *
* @param in the buffer with the input data to be encrypted * @param in the buffer with the input data to be encrypted
...@@ -422,15 +424,18 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -422,15 +424,18 @@ final class GaloisCounterMode extends FeedbackCipher {
int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) { int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
checkDataLength(processed, len); checkDataLength(processed, len);
if ((len % blockSize) != 0) { ArrayUtil.blockSizeCheck(len, blockSize);
throw new ProviderException("Internal error in input buffering");
}
processAAD(); processAAD();
if (len > 0) { if (len > 0) {
ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
ArrayUtil.nullAndBoundsCheck(out, outOfs, len);
gctrPAndC.update(in, inOfs, len, out, outOfs); gctrPAndC.update(in, inOfs, len, out, outOfs);
processed += len; processed += len;
ghashAllToS.update(out, outOfs, len); ghashAllToS.update(out, outOfs, len);
} }
return len; return len;
} }
...@@ -450,7 +455,10 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -450,7 +455,10 @@ final class GaloisCounterMode extends FeedbackCipher {
throw new ShortBufferException throw new ShortBufferException
("Can't fit both data and tag into one buffer"); ("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"); throw new ShortBufferException("Output buffer too small");
} }
...@@ -458,6 +466,8 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -458,6 +466,8 @@ final class GaloisCounterMode extends FeedbackCipher {
processAAD(); processAAD();
if (len > 0) { if (len > 0) {
ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
doLastBlock(in, inOfs, len, out, outOfs, true); doLastBlock(in, inOfs, len, out, outOfs, true);
} }
...@@ -493,15 +503,14 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -493,15 +503,14 @@ final class GaloisCounterMode extends FeedbackCipher {
int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) { int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
checkDataLength(ibuffer.size(), len); checkDataLength(ibuffer.size(), len);
if ((len % blockSize) != 0) { ArrayUtil.blockSizeCheck(len, blockSize);
throw new ProviderException("Internal error in input buffering");
}
processAAD(); processAAD();
if (len > 0) { if (len > 0) {
// store internally until decryptFinal is called because // store internally until decryptFinal is called because
// spec mentioned that only return recovered data after tag // spec mentioned that only return recovered data after tag
// is successfully verified // is successfully verified
ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
ibuffer.write(in, inOfs, len); ibuffer.write(in, inOfs, len);
} }
return 0; return 0;
...@@ -530,22 +539,28 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -530,22 +539,28 @@ final class GaloisCounterMode extends FeedbackCipher {
if (len < tagLenBytes) { if (len < tagLenBytes) {
throw new AEADBadTagException("Input too short - need tag"); throw new AEADBadTagException("Input too short - need tag");
} }
// do this check here can also catch the potential integer overflow // do this check here can also catch the potential integer overflow
// scenario for the subsequent output buffer capacity check. // scenario for the subsequent output buffer capacity check.
checkDataLength(ibuffer.size(), (len - tagLenBytes)); 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"); throw new ShortBufferException("Output buffer too small");
} }
processAAD(); processAAD();
ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
// get the trailing tag bytes from 'in' // get the trailing tag bytes from 'in'
byte[] tag = new byte[tagLenBytes]; byte[] tag = new byte[tagLenBytes];
System.arraycopy(in, inOfs + len - tagLenBytes, tag, 0, tagLenBytes); System.arraycopy(in, inOfs + len - tagLenBytes, tag, 0, tagLenBytes);
len -= tagLenBytes; len -= tagLenBytes;
if (len != 0) { if (len > 0) {
ibuffer.write(in, inOfs, len); ibuffer.write(in, inOfs, len);
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,6 +27,7 @@ package com.sun.crypto.provider; ...@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.ProviderException; import java.security.ProviderException;
import sun.security.util.ArrayUtil;
/** /**
* This class represents ciphers in output-feedback (OFB) mode. * This class represents ciphers in output-feedback (OFB) mode.
...@@ -148,10 +149,10 @@ final class OutputFeedback extends FeedbackCipher { ...@@ -148,10 +149,10 @@ final class OutputFeedback extends FeedbackCipher {
*/ */
int encrypt(byte[] plain, int plainOffset, int plainLen, int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) { 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 nShift = blockSize - numBytes;
int loopCount = plainLen / numBytes; int loopCount = plainLen / numBytes;
...@@ -189,6 +190,9 @@ final class OutputFeedback extends FeedbackCipher { ...@@ -189,6 +190,9 @@ final class OutputFeedback extends FeedbackCipher {
*/ */
int encryptFinal(byte[] plain, int plainOffset, int plainLen, int encryptFinal(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) { byte[] cipher, int cipherOffset) {
ArrayUtil.nullAndBoundsCheck(plain, plainOffset, plainLen);
ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, plainLen);
int oddBytes = plainLen % numBytes; int oddBytes = plainLen % numBytes;
int len = encrypt(plain, plainOffset, (plainLen - oddBytes), int len = encrypt(plain, plainOffset, (plainLen - oddBytes),
cipher, cipherOffset); cipher, cipherOffset);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,6 +27,7 @@ package com.sun.crypto.provider; ...@@ -27,6 +27,7 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.ProviderException; import java.security.ProviderException;
import sun.security.util.ArrayUtil;
/** /**
...@@ -136,9 +137,10 @@ final class PCBC extends FeedbackCipher { ...@@ -136,9 +137,10 @@ final class PCBC extends FeedbackCipher {
int encrypt(byte[] plain, int plainOffset, int plainLen, int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) byte[] cipher, int cipherOffset)
{ {
if ((plainLen % blockSize) != 0) { ArrayUtil.blockSizeCheck(plainLen, blockSize);
throw new ProviderException("Internal error in input buffering"); ArrayUtil.nullAndBoundsCheck(plain, plainOffset, plainLen);
} ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, plainLen);
int i; int i;
int endIndex = plainOffset + plainLen; int endIndex = plainOffset + plainLen;
...@@ -176,9 +178,10 @@ final class PCBC extends FeedbackCipher { ...@@ -176,9 +178,10 @@ final class PCBC extends FeedbackCipher {
int decrypt(byte[] cipher, int cipherOffset, int cipherLen, int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) byte[] plain, int plainOffset)
{ {
if ((cipherLen % blockSize) != 0) { ArrayUtil.blockSizeCheck(cipherLen, blockSize);
throw new ProviderException("Internal error in input buffering"); ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, cipherLen);
} ArrayUtil.nullAndBoundsCheck(plain, plainOffset, cipherLen);
int i; int i;
int endIndex = cipherOffset + cipherLen; int endIndex = cipherOffset + cipherLen;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -374,7 +374,10 @@ public class JPEGImageReader extends ImageReader { ...@@ -374,7 +374,10 @@ public class JPEGImageReader extends ImageReader {
// And set current image since we've read it now // And set current image since we've read it now
currentImage = 0; 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); Long pos = (Long) imagePositions.get(imagePositions.size()-1);
iis.flushBefore(pos.longValue()); iis.flushBefore(pos.longValue());
} }
...@@ -491,6 +494,11 @@ public class JPEGImageReader extends ImageReader { ...@@ -491,6 +494,11 @@ public class JPEGImageReader extends ImageReader {
if (!tablesOnlyChecked) { if (!tablesOnlyChecked) {
checkTablesOnly(); 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()) { if (imageIndex < imagePositions.size()) {
iis.seek(((Long)(imagePositions.get(imageIndex))).longValue()); iis.seek(((Long)(imagePositions.get(imageIndex))).longValue());
} else { } else {
......
/* /*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
*/ */
package java.lang; package java.lang;
import java.io.*;
import java.util.*; import java.io.*;
import java.util.*;
/** /**
* The {@code Throwable} class is the superclass of all errors and * The {@code Throwable} class is the superclass of all errors and
...@@ -912,25 +913,37 @@ public class Throwable implements Serializable { ...@@ -912,25 +913,37 @@ public class Throwable implements Serializable {
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
s.defaultReadObject(); // read in all fields s.defaultReadObject(); // read in all fields
if (suppressedExceptions != null) {
List<Throwable> suppressed = null; // Set suppressed exceptions and stack trace elements fields
if (suppressedExceptions.isEmpty()) { // to marker values until the contents from the serial stream
// Use the sentinel for a zero-length list // are validated.
suppressed = SUPPRESSED_SENTINEL; List<Throwable> candidateSuppressedExceptions = suppressedExceptions;
} else { // Copy Throwables to new list suppressedExceptions = SUPPRESSED_SENTINEL;
suppressed = new ArrayList<>(1);
for (Throwable t : suppressedExceptions) { StackTraceElement[] candidateStackTrace = stackTrace;
stackTrace = UNASSIGNED_STACK.clone();
if (candidateSuppressedExceptions != null) {
int suppressedSize = validateSuppressedExceptionsList(candidateSuppressedExceptions);
if (suppressedSize > 0) { // Copy valid Throwables to new list
List<Throwable> suppList = new ArrayList<Throwable>(Math.min(100, suppressedSize));
for (Throwable t : candidateSuppressedExceptions) {
// Enforce constraints on suppressed exceptions in // Enforce constraints on suppressed exceptions in
// case of corrupt or malicious stream. // case of corrupt or malicious stream.
if (t == null) if (t == null)
throw new NullPointerException(NULL_CAUSE_MESSAGE); throw new NullPointerException(NULL_CAUSE_MESSAGE);
if (t == this) if (t == this)
throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE); throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
suppressed.add(t); suppList.add(t);
} }
// If there are any invalid suppressed exceptions,
// implicitly use the sentinel value assigned earlier.
suppressedExceptions = suppList;
} }
suppressedExceptions = suppressed; } else {
} // else a null suppressedExceptions field remains null suppressedExceptions = null;
}
/* /*
* For zero-length stack traces, use a clone of * For zero-length stack traces, use a clone of
...@@ -941,25 +954,41 @@ public class Throwable implements Serializable { ...@@ -941,25 +954,41 @@ public class Throwable implements Serializable {
* the stackTrace needs to be constructed from the information * the stackTrace needs to be constructed from the information
* in backtrace. * in backtrace.
*/ */
if (stackTrace != null) { if (candidateStackTrace != null) {
if (stackTrace.length == 0) { // Work from a clone of the candidateStackTrace to ensure
stackTrace = UNASSIGNED_STACK.clone(); // consistency of checks.
} else if (stackTrace.length == 1 && candidateStackTrace = candidateStackTrace.clone();
if (candidateStackTrace.length >= 1) {
if (candidateStackTrace.length == 1 &&
// Check for the marker of an immutable stack trace // Check for the marker of an immutable stack trace
SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) { SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(candidateStackTrace[0])) {
stackTrace = null; stackTrace = null;
} else { // Verify stack trace elements are non-null. } else { // Verify stack trace elements are non-null.
for(StackTraceElement ste : stackTrace) { for (StackTraceElement ste : candidateStackTrace) {
if (ste == null) if (ste == null)
throw new NullPointerException("null StackTraceElement in serial stream. "); throw new NullPointerException("null StackTraceElement in serial stream.");
}
stackTrace = candidateStackTrace;
} }
} }
}
// A null stackTrace field in the serial form can result from
// an exception serialized without that field in older JDK
// releases; treat such exceptions as having empty stack
// traces by leaving stackTrace assigned to a clone of
// UNASSIGNED_STACK.
}
private int validateSuppressedExceptionsList(List<Throwable> deserSuppressedExceptions)
throws IOException {
if (Object.class.getClassLoader() != deserSuppressedExceptions.getClass().getClassLoader()) {
throw new StreamCorruptedException("List implementation not on the bootclasspath.");
} else { } else {
// A null stackTrace field in the serial form can result int size = deserSuppressedExceptions.size();
// from an exception serialized without that field in if (size < 0) {
// older JDK releases; treat such exceptions as having throw new StreamCorruptedException("Negative list size reported.");
// empty stack traces. }
stackTrace = UNASSIGNED_STACK.clone(); return size;
} }
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -33,6 +33,7 @@ import java.io.ObjectStreamField; ...@@ -33,6 +33,7 @@ import java.io.ObjectStreamField;
import java.io.ObjectInputStream.GetField; import java.io.ObjectInputStream.GetField;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import sun.net.util.IPAddressUtil;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
/** /**
...@@ -414,13 +415,19 @@ public final class URL implements java.io.Serializable { ...@@ -414,13 +415,19 @@ public final class URL implements java.io.Serializable {
} }
ref = parts.getRef(); 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 // right now, but worth considering for future reference. -br
if (handler == null && if (handler == null &&
(handler = getURLStreamHandler(protocol)) == null) { (handler = getURLStreamHandler(protocol)) == null) {
throw new MalformedURLException("unknown protocol: " + protocol); throw new MalformedURLException("unknown protocol: " + protocol);
} }
this.handler = handler; 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 { ...@@ -943,7 +950,12 @@ public final class URL implements java.io.Serializable {
* @since 1.5 * @since 1.5
*/ */
public URI toURI() throws URISyntaxException { 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 { ...@@ -1400,6 +1412,10 @@ public final class URL implements java.io.Serializable {
return replacementURL; return replacementURL;
} }
boolean isBuiltinStreamHandler(URLStreamHandler handler) {
return isBuiltinStreamHandler(handler.getClass().getName());
}
private boolean isBuiltinStreamHandler(String handlerClassName) { private boolean isBuiltinStreamHandler(String handlerClassName) {
return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX)); return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -532,12 +532,15 @@ public abstract class URLStreamHandler { ...@@ -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) * @see java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
* @since 1.3 * @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 authority, String userInfo, String path,
String query, String ref) { String query, String ref) {
if (this != u.handler) { if (this != u.handler) {
throw new SecurityException("handler for url different from " + throw new SecurityException("handler for url different from " +
"this handler"); "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. // ensure that no one can reset the protocol on a given URL.
u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref); u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -425,7 +425,8 @@ public final class AccessController { ...@@ -425,7 +425,8 @@ public final class AccessController {
throw new NullPointerException("null permissions parameter"); throw new NullPointerException("null permissions parameter");
} }
Class <?> caller = Reflection.getCallerClass(); 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)); caller, parent, context, perms));
} }
...@@ -710,7 +711,8 @@ public final class AccessController { ...@@ -710,7 +711,8 @@ public final class AccessController {
throw new NullPointerException("null permissions parameter"); throw new NullPointerException("null permissions parameter");
} }
Class <?> caller = Reflection.getCallerClass(); 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));
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package java.util; package java.util;
import java.io.Serializable; import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Array; import java.lang.reflect.Array;
...@@ -37,6 +38,7 @@ import java.util.function.UnaryOperator; ...@@ -37,6 +38,7 @@ import java.util.function.UnaryOperator;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
import sun.misc.SharedSecrets;
/** /**
* This class consists exclusively of static methods that operate on or return * This class consists exclusively of static methods that operate on or return
...@@ -5075,6 +5077,11 @@ public class Collections { ...@@ -5075,6 +5077,11 @@ public class Collections {
public Spliterator<E> spliterator() { public Spliterator<E> spliterator() {
return stream().spliterator(); return stream().spliterator();
} }
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
SharedSecrets.getJavaOISAccess().checkArray(ois, Object[].class, n);
}
} }
/** /**
......
/*
* 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<String, List<Integer>, ? extends RuntimeException> oobef,
String checkKind,
Integer... args) {
List<Integer> 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<String, List<Integer>, ? extends RuntimeException> oobe,
int index, int length) {
return outOfBounds(oobe, "checkIndex", index, length);
}
private static RuntimeException outOfBoundsCheckFromToIndex(
BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
int fromIndex, int toIndex, int length) {
return outOfBounds(oobe, "checkFromToIndex", fromIndex, toIndex, length);
}
private static RuntimeException outOfBoundsCheckFromIndexSize(
BiFunction<String, List<Integer>, ? 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.
*
* <p>The exception formatter accepts two arguments: a {@code String}
* describing the out-of-bounds range check that failed, referred to as the
* <em>check kind</em>; and a {@code List<Integer>} containing the
* out-of-bound integer values that failed the check. The list of
* out-of-bound values is not modified.
*
* <p>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).
*
* <p>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:
* <pre>{@code
* static final
* BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException> AIOOBEF =
* outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new);
* }</pre>
* 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}:
* <pre>{@code
* checkIndex(index, limit, AIOOBEF);
* }</pre>
* 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:
* <pre>{@code
* AIOOBEF.apply("checkIndex", List.of(index, limit));
* }</pre>
*
* @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 <X> 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 <X extends RuntimeException>
BiFunction<String, List<Integer>, X> outOfBoundsExceptionFormatter(Function<String, X> f) {
// Use anonymous class to avoid bootstrap issues if this method is
// used early in startup
return new BiFunction<String, List<Integer>, X>() {
@Override
public X apply(String checkKind, List<Integer> args) {
return f.apply(outOfBoundsMessage(checkKind, args));
}
};
}
private static String outOfBoundsMessage(String checkKind, List<Integer> 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, %<d + %d) out-of-bounds for length %d",
args.get(0), args.get(1), args.get(2));
default:
return String.format("Range check failed: %s %s", checkKind, args);
}
}
/**
* Checks if the {@code index} is within the bounds of the range from
* {@code 0} (inclusive) to {@code length} (exclusive).
*
* <p>The {@code index} is defined to be out-of-bounds if any of the
* following inequalities is true:
* <ul>
* <li>{@code index < 0}</li>
* <li>{@code index >= length}</li>
* <li>{@code length < 0}, which is implied from the former inequalities</li>
* </ul>
*
* <p>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 <X> 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 <X extends RuntimeException>
int checkIndex(int index, int length,
BiFunction<String, List<Integer>, 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).
*
* <p>The sub-range is defined to be out-of-bounds if any of the following
* inequalities is true:
* <ul>
* <li>{@code fromIndex < 0}</li>
* <li>{@code fromIndex > toIndex}</li>
* <li>{@code toIndex > length}</li>
* <li>{@code length < 0}, which is implied from the former inequalities</li>
* </ul>
*
* <p>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 <X> 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 <X extends RuntimeException>
int checkFromToIndex(int fromIndex, int toIndex, int length,
BiFunction<String, List<Integer>, 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).
*
* <p>The sub-range is defined to be out-of-bounds if any of the following
* inequalities is true:
* <ul>
* <li>{@code fromIndex < 0}</li>
* <li>{@code size < 0}</li>
* <li>{@code fromIndex + size > length}, taking into account integer overflow</li>
* <li>{@code length < 0}, which is implied from the former inequalities</li>
* </ul>
*
* <p>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 <X> 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 <X extends RuntimeException>
int checkFromIndexSize(int fromIndex, int size, int length,
BiFunction<String, List<Integer>, X> oobef) {
if ((length | fromIndex | size) < 0 || size > length - fromIndex)
throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length);
return fromIndex;
}
}
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
package sun.net.util; package sun.net.util;
import java.net.URL;
import java.util.Arrays;
public class IPAddressUtil { public class IPAddressUtil {
private final static int INADDR4SZ = 4; private final static int INADDR4SZ = 4;
private final static int INADDR16SZ = 16; private final static int INADDR16SZ = 16;
...@@ -287,4 +290,182 @@ public class IPAddressUtil { ...@@ -287,4 +290,182 @@ public class IPAddressUtil {
} }
return false; 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;
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -36,6 +36,7 @@ import java.io.BufferedInputStream; ...@@ -36,6 +36,7 @@ import java.io.BufferedInputStream;
import java.io.FilterInputStream; import java.io.FilterInputStream;
import java.io.FilterOutputStream; import java.io.FilterOutputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.SocketPermission; import java.net.SocketPermission;
import java.net.UnknownHostException; import java.net.UnknownHostException;
...@@ -47,6 +48,7 @@ import java.util.StringTokenizer; ...@@ -47,6 +48,7 @@ import java.util.StringTokenizer;
import java.util.Iterator; import java.util.Iterator;
import java.security.Permission; import java.security.Permission;
import sun.net.NetworkClient; import sun.net.NetworkClient;
import sun.net.util.IPAddressUtil;
import sun.net.www.MessageHeader; import sun.net.www.MessageHeader;
import sun.net.www.MeteredStream; import sun.net.www.MeteredStream;
import sun.net.www.URLConnection; import sun.net.www.URLConnection;
...@@ -155,6 +157,21 @@ public class FtpURLConnection extends 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. * Creates an FtpURLConnection from a URL.
* *
...@@ -168,7 +185,7 @@ public class FtpURLConnection extends URLConnection { ...@@ -168,7 +185,7 @@ public class FtpURLConnection extends URLConnection {
* Same as FtpURLconnection(URL) with a per connection proxy specified * Same as FtpURLconnection(URL) with a per connection proxy specified
*/ */
FtpURLConnection(URL url, Proxy p) { FtpURLConnection(URL url, Proxy p) {
super(url); super(checkURL(url));
instProxy = p; instProxy = p;
host = url.getHost(); host = url.getHost();
port = url.getPort(); port = url.getPort();
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -66,6 +66,7 @@ import java.util.HashSet; ...@@ -66,6 +66,7 @@ import java.util.HashSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.Set; import java.util.Set;
import sun.net.*; import sun.net.*;
import sun.net.util.IPAddressUtil;
import sun.net.www.*; import sun.net.www.*;
import sun.net.www.http.HttpClient; import sun.net.www.http.HttpClient;
import sun.net.www.http.PosterOutputStream; import sun.net.www.http.PosterOutputStream;
...@@ -850,8 +851,13 @@ public class HttpURLConnection extends java.net.HttpURLConnection { ...@@ -850,8 +851,13 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
throw new MalformedURLException("Illegal character in URL"); throw new MalformedURLException("Illegal character in URL");
} }
} }
String s = IPAddressUtil.checkAuthority(u);
if (s != null) {
throw new MalformedURLException(s);
}
return u; return u;
} }
protected HttpURLConnection(URL u, Proxy p, Handler handler) protected HttpURLConnection(URL u, Proxy p, Handler handler)
throws IOException { throws IOException {
super(checkURL(u)); super(checkURL(u));
......
...@@ -45,6 +45,7 @@ import java.security.Permission; ...@@ -45,6 +45,7 @@ import java.security.Permission;
import java.security.Principal; import java.security.Principal;
import java.util.Map; import java.util.Map;
import java.util.List; import java.util.List;
import sun.net.util.IPAddressUtil;
import sun.net.www.http.HttpClient; import sun.net.www.http.HttpClient;
/** /**
...@@ -86,6 +87,10 @@ public class HttpsURLConnectionImpl ...@@ -86,6 +87,10 @@ public class HttpsURLConnectionImpl
throw new MalformedURLException("Illegal character in URL"); throw new MalformedURLException("Illegal character in URL");
} }
} }
String s = IPAddressUtil.checkAuthority(u);
if (s != null) {
throw new MalformedURLException(s);
}
return u; return u;
} }
// For both copies of the file, uncomment one line and comment the other // For both copies of the file, uncomment one line and comment the other
...@@ -333,7 +338,7 @@ public class HttpsURLConnectionImpl ...@@ -333,7 +338,7 @@ public class HttpsURLConnectionImpl
* @param key the keyword by which the request is known * @param key the keyword by which the request is known
* (e.g., "<code>accept</code>"). * (e.g., "<code>accept</code>").
* @param value the value associated with it. * @param value the value associated with it.
* @see #getRequestProperties(java.lang.String) * @see #getRequestProperty(java.lang.String)
* @since 1.4 * @since 1.4
*/ */
public void addRequestProperty(String key, String value) { public void addRequestProperty(String key, String value) {
......
...@@ -29,6 +29,7 @@ import java.security.MessageDigestSpi; ...@@ -29,6 +29,7 @@ import java.security.MessageDigestSpi;
import java.security.DigestException; import java.security.DigestException;
import java.security.ProviderException; import java.security.ProviderException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
/** /**
* Common base message digest implementation for the Sun provider. * Common base message digest implementation for the Sun provider.
...@@ -137,12 +138,35 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable { ...@@ -137,12 +138,35 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable {
// compress complete blocks // compress complete blocks
private int implCompressMultiBlock(byte[] b, int ofs, int limit) { 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) { for (; ofs <= limit; ofs += blockSize) {
implCompress(b, ofs); implCompress(b, ofs);
} }
return 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. // reset this object. See JCA doc.
protected final void engineReset() { protected final void engineReset() {
if (bytesProcessed == 0) { if (bytesProcessed == 0) {
......
...@@ -27,6 +27,8 @@ package sun.security.provider; ...@@ -27,6 +27,8 @@ package sun.security.provider;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import static sun.security.provider.ByteArrayAccess.*; import static sun.security.provider.ByteArrayAccess.*;
/** /**
...@@ -123,8 +125,26 @@ public final class SHA extends DigestBase { ...@@ -123,8 +125,26 @@ public final class SHA extends DigestBase {
* "old" NIST Secure Hash Algorithm. * "old" NIST Secure Hash Algorithm.
*/ */
void implCompress(byte[] buf, int ofs) { 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); 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 first 16 ints have the byte stream, compute the rest of
// the buffer // the buffer
for (int t = 16; t <= 79; t++) { for (int t = 16; t <= 79; t++) {
......
...@@ -27,6 +27,8 @@ package sun.security.provider; ...@@ -27,6 +27,8 @@ package sun.security.provider;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import static sun.security.provider.ByteArrayAccess.*; import static sun.security.provider.ByteArrayAccess.*;
/** /**
...@@ -193,8 +195,26 @@ abstract class SHA2 extends DigestBase { ...@@ -193,8 +195,26 @@ abstract class SHA2 extends DigestBase {
* Process the current block to update the state variable state. * Process the current block to update the state variable state.
*/ */
void implCompress(byte[] buf, int ofs) { 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); 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 first 16 ints are from the byte stream, compute the rest of
// the W[]'s // the W[]'s
for (int t = 16; t < ITERATION; t++) { for (int t = 16; t < ITERATION; t++) {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
package sun.security.provider; package sun.security.provider;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import static sun.security.provider.ByteArrayAccess.*; import static sun.security.provider.ByteArrayAccess.*;
...@@ -209,8 +210,26 @@ abstract class SHA5 extends DigestBase { ...@@ -209,8 +210,26 @@ abstract class SHA5 extends DigestBase {
* "old" NIST Secure Hash Algorithm. * "old" NIST Secure Hash Algorithm.
*/ */
final void implCompress(byte[] buf, int ofs) { 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); 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 first 16 longs are from the byte stream, compute the rest of
// the W[]'s // the W[]'s
for (int t = 16; t < ITERATION; t++) { for (int t = 16; t < ITERATION; t++) {
......
...@@ -1114,8 +1114,9 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager ...@@ -1114,8 +1114,9 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
checkAdditionalTrust(chain, authType, engine, false); checkAdditionalTrust(chain, authType, engine, false);
} }
private void checkAdditionalTrust(X509Certificate[] chain, String authType, private void checkAdditionalTrust(X509Certificate[] chain,
Socket socket, boolean isClient) throws CertificateException { String authType, Socket socket,
boolean checkClientTrusted) throws CertificateException {
if (socket != null && socket.isConnected() && if (socket != null && socket.isConnected() &&
socket instanceof SSLSocket) { socket instanceof SSLSocket) {
...@@ -1129,9 +1130,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager ...@@ -1129,9 +1130,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
String identityAlg = sslSocket.getSSLParameters(). String identityAlg = sslSocket.getSSLParameters().
getEndpointIdentificationAlgorithm(); getEndpointIdentificationAlgorithm();
if (identityAlg != null && identityAlg.length() != 0) { if (identityAlg != null && identityAlg.length() != 0) {
String hostname = session.getPeerHost(); X509TrustManagerImpl.checkIdentity(session, chain,
X509TrustManagerImpl.checkIdentity( identityAlg, checkClientTrusted);
hostname, chain[0], identityAlg);
} }
// try the best to check the algorithm constraints // try the best to check the algorithm constraints
...@@ -1155,12 +1155,13 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager ...@@ -1155,12 +1155,13 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
constraints = new SSLAlgorithmConstraints(sslSocket, true); constraints = new SSLAlgorithmConstraints(sslSocket, true);
} }
checkAlgorithmConstraints(chain, constraints, isClient); checkAlgorithmConstraints(chain, constraints, checkClientTrusted);
} }
} }
private void checkAdditionalTrust(X509Certificate[] chain, String authType, private void checkAdditionalTrust(X509Certificate[] chain,
SSLEngine engine, boolean isClient) throws CertificateException { String authType, SSLEngine engine,
boolean checkClientTrusted) throws CertificateException {
if (engine != null) { if (engine != null) {
SSLSession session = engine.getHandshakeSession(); SSLSession session = engine.getHandshakeSession();
if (session == null) { if (session == null) {
...@@ -1171,9 +1172,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager ...@@ -1171,9 +1172,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
String identityAlg = engine.getSSLParameters(). String identityAlg = engine.getSSLParameters().
getEndpointIdentificationAlgorithm(); getEndpointIdentificationAlgorithm();
if (identityAlg != null && identityAlg.length() != 0) { if (identityAlg != null && identityAlg.length() != 0) {
String hostname = session.getPeerHost(); X509TrustManagerImpl.checkIdentity(session, chain,
X509TrustManagerImpl.checkIdentity( identityAlg, checkClientTrusted);
hostname, chain[0], identityAlg);
} }
// try the best to check the algorithm constraints // try the best to check the algorithm constraints
...@@ -1197,12 +1197,13 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager ...@@ -1197,12 +1197,13 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
constraints = new SSLAlgorithmConstraints(engine, true); constraints = new SSLAlgorithmConstraints(engine, true);
} }
checkAlgorithmConstraints(chain, constraints, isClient); checkAlgorithmConstraints(chain, constraints, checkClientTrusted);
} }
} }
private void checkAlgorithmConstraints(X509Certificate[] chain, private void checkAlgorithmConstraints(X509Certificate[] chain,
AlgorithmConstraints constraints, boolean isClient) throws CertificateException { AlgorithmConstraints constraints,
boolean checkClientTrusted) throws CertificateException {
try { try {
// Does the certificate chain end with a trusted certificate? // Does the certificate chain end with a trusted certificate?
...@@ -1222,7 +1223,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager ...@@ -1222,7 +1223,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
if (checkedLength >= 0) { if (checkedLength >= 0) {
AlgorithmChecker checker = AlgorithmChecker checker =
new AlgorithmChecker(constraints, null, 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); checker.init(false);
for (int i = checkedLength; i >= 0; i--) { for (int i = checkedLength; i >= 0; i--) {
Certificate cert = chain[i]; Certificate cert = chain[i];
......
...@@ -145,7 +145,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -145,7 +145,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
} }
private Validator checkTrustedInit(X509Certificate[] chain, private Validator checkTrustedInit(X509Certificate[] chain,
String authType, boolean isClient) { String authType, boolean checkClientTrusted) {
if (chain == null || chain.length == 0) { if (chain == null || chain.length == 0) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"null or zero-length certificate chain"); "null or zero-length certificate chain");
...@@ -157,7 +157,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -157,7 +157,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
} }
Validator v = null; Validator v = null;
if (isClient) { if (checkClientTrusted) {
v = clientValidator; v = clientValidator;
if (v == null) { if (v == null) {
synchronized (this) { synchronized (this) {
...@@ -187,9 +187,10 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -187,9 +187,10 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
} }
private void checkTrusted(X509Certificate[] chain, String authType, private void checkTrusted(X509Certificate[] chain,
Socket socket, boolean isClient) throws CertificateException { String authType, Socket socket,
Validator v = checkTrustedInit(chain, authType, isClient); boolean checkClientTrusted) throws CertificateException {
Validator v = checkTrustedInit(chain, authType, checkClientTrusted);
AlgorithmConstraints constraints = null; AlgorithmConstraints constraints = null;
if ((socket != null) && socket.isConnected() && if ((socket != null) && socket.isConnected() &&
...@@ -205,8 +206,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -205,8 +206,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
String identityAlg = sslSocket.getSSLParameters(). String identityAlg = sslSocket.getSSLParameters().
getEndpointIdentificationAlgorithm(); getEndpointIdentificationAlgorithm();
if (identityAlg != null && identityAlg.length() != 0) { if (identityAlg != null && identityAlg.length() != 0) {
checkIdentity(session, chain[0], identityAlg, isClient, checkIdentity(session, chain, identityAlg, checkClientTrusted);
getRequestedServerNames(socket));
} }
// create the algorithm constraints // create the algorithm constraints
...@@ -231,7 +231,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -231,7 +231,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
} }
X509Certificate[] trustedChain = null; X509Certificate[] trustedChain = null;
if (isClient) { if (checkClientTrusted) {
trustedChain = validate(v, chain, constraints, null); trustedChain = validate(v, chain, constraints, null);
} else { } else {
trustedChain = validate(v, chain, constraints, authType); trustedChain = validate(v, chain, constraints, authType);
...@@ -242,9 +242,10 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -242,9 +242,10 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
} }
} }
private void checkTrusted(X509Certificate[] chain, String authType, private void checkTrusted(X509Certificate[] chain,
SSLEngine engine, boolean isClient) throws CertificateException { String authType, SSLEngine engine,
Validator v = checkTrustedInit(chain, authType, isClient); boolean checkClientTrusted) throws CertificateException {
Validator v = checkTrustedInit(chain, authType, checkClientTrusted);
AlgorithmConstraints constraints = null; AlgorithmConstraints constraints = null;
if (engine != null) { if (engine != null) {
...@@ -257,8 +258,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -257,8 +258,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
String identityAlg = engine.getSSLParameters(). String identityAlg = engine.getSSLParameters().
getEndpointIdentificationAlgorithm(); getEndpointIdentificationAlgorithm();
if (identityAlg != null && identityAlg.length() != 0) { if (identityAlg != null && identityAlg.length() != 0) {
checkIdentity(session, chain[0], identityAlg, isClient, checkIdentity(session, chain, identityAlg, checkClientTrusted);
getRequestedServerNames(engine));
} }
// create the algorithm constraints // create the algorithm constraints
...@@ -283,7 +283,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -283,7 +283,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
} }
X509Certificate[] trustedChain = null; X509Certificate[] trustedChain = null;
if (isClient) { if (checkClientTrusted) {
trustedChain = validate(v, chain, constraints, null); trustedChain = validate(v, chain, constraints, null);
} else { } else {
trustedChain = validate(v, chain, constraints, authType); trustedChain = validate(v, chain, constraints, authType);
...@@ -373,13 +373,8 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -373,13 +373,8 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
if (socket != null && socket.isConnected() && if (socket != null && socket.isConnected() &&
socket instanceof SSLSocket) { socket instanceof SSLSocket) {
SSLSocket sslSocket = (SSLSocket)socket; return getRequestedServerNames(
SSLSession session = sslSocket.getHandshakeSession(); ((SSLSocket)socket).getHandshakeSession());
if (session != null && (session instanceof ExtendedSSLSession)) {
ExtendedSSLSession extSession = (ExtendedSSLSession)session;
return extSession.getRequestedServerNames();
}
} }
return Collections.<SNIServerName>emptyList(); return Collections.<SNIServerName>emptyList();
...@@ -388,12 +383,16 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -388,12 +383,16 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
// Also used by X509KeyManagerImpl // Also used by X509KeyManagerImpl
static List<SNIServerName> getRequestedServerNames(SSLEngine engine) { static List<SNIServerName> getRequestedServerNames(SSLEngine engine) {
if (engine != null) { if (engine != null) {
SSLSession session = engine.getHandshakeSession(); return getRequestedServerNames(engine.getHandshakeSession());
}
if (session != null && (session instanceof ExtendedSSLSession)) { return Collections.<SNIServerName>emptyList();
ExtendedSSLSession extSession = (ExtendedSSLSession)session; }
return extSession.getRequestedServerNames();
} private static List<SNIServerName> getRequestedServerNames(
SSLSession session) {
if (session != null && (session instanceof ExtendedSSLSession)) {
return ((ExtendedSSLSession)session).getRequestedServerNames();
} }
return Collections.<SNIServerName>emptyList(); return Collections.<SNIServerName>emptyList();
...@@ -414,22 +413,23 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -414,22 +413,23 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
* the identity checking aginst the server_name extension if present, and * the identity checking aginst the server_name extension if present, and
* may failove to peer host checking. * may failove to peer host checking.
*/ */
private static void checkIdentity(SSLSession session, static void checkIdentity(SSLSession session,
X509Certificate cert, X509Certificate [] trustedChain,
String algorithm, String algorithm,
boolean isClient, boolean checkClientTrusted) throws CertificateException {
List<SNIServerName> sniNames) throws CertificateException {
boolean identifiable = false; boolean identifiable = false;
String peerHost = session.getPeerHost(); String peerHost = session.getPeerHost();
if (isClient) { if (!checkClientTrusted) {
String hostname = getHostNameInSNI(sniNames); List<SNIServerName> sniNames = getRequestedServerNames(session);
if (hostname != null) { String sniHostName = getHostNameInSNI(sniNames);
if (sniHostName != null) {
try { try {
checkIdentity(hostname, cert, algorithm); checkIdentity(sniHostName,
trustedChain[0], algorithm);
identifiable = true; identifiable = true;
} catch (CertificateException ce) { } catch (CertificateException ce) {
if (hostname.equalsIgnoreCase(peerHost)) { if (sniHostName.equalsIgnoreCase(peerHost)) {
throw ce; throw ce;
} }
...@@ -439,7 +439,8 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager ...@@ -439,7 +439,8 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
} }
if (!identifiable) { if (!identifiable) {
checkIdentity(peerHost, cert, algorithm); checkIdentity(peerHost,
trustedChain[0], algorithm);
} }
} }
......
...@@ -25,12 +25,34 @@ ...@@ -25,12 +25,34 @@
package sun.security.util; 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. * This class holds the various utility methods for array range checks.
*/ */
public final class ArrayUtil { public final class ArrayUtil {
private static final BiFunction<String, List<Integer>,
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) { private static void swap(byte[] arr, int i, int j) {
byte tmp = arr[i]; byte tmp = arr[i];
arr[i] = arr[j]; arr[i] = arr[j];
...@@ -48,4 +70,3 @@ public final class ArrayUtil { ...@@ -48,4 +70,3 @@ public final class ArrayUtil {
} }
} }
} }
...@@ -92,37 +92,41 @@ class DerIndefLenConverter { ...@@ -92,37 +92,41 @@ class DerIndefLenConverter {
private void parseTag() throws IOException { private void parseTag() throws IOException {
if (dataPos == dataSize) if (dataPos == dataSize)
return; return;
if (isEOC(data[dataPos]) && (data[dataPos + 1] == 0)) { try {
int numOfEncapsulatedLenBytes = 0; if (isEOC(data[dataPos]) && (data[dataPos + 1] == 0)) {
Object elem = null; int numOfEncapsulatedLenBytes = 0;
int index; Object elem = null;
for (index = ndefsList.size()-1; index >= 0; index--) { int index;
// Determine the first element in the vector that does not for (index = ndefsList.size()-1; index >= 0; index--) {
// have a matching EOC // Determine the first element in the vector that does not
elem = ndefsList.get(index); // have a matching EOC
if (elem instanceof Integer) { elem = ndefsList.get(index);
break; if (elem instanceof Integer) {
} else { break;
numOfEncapsulatedLenBytes += ((byte[])elem).length - 3; } 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) { dataPos++;
throw new IOException("EOC does not have matching " + } catch (IndexOutOfBoundsException iobe) {
"indefinite-length tag"); throw new IOException(iobe);
}
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++;
} }
/** /**
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -262,18 +262,17 @@ public class HostnameChecker { ...@@ -262,18 +262,17 @@ public class HostnameChecker {
* The matching is performed as per RFC 2818 rules for TLS and * The matching is performed as per RFC 2818 rules for TLS and
* RFC 2830 rules for LDAP.<p> * RFC 2830 rules for LDAP.<p>
* *
* The <code>name</code> parameter should represent a DNS name. * The <code>name</code> parameter should represent a DNS name. The
* The <code>template</code> parameter * <code>template</code> parameter may contain the wildcard character '*'.
* may contain the wildcard character *
*/ */
private boolean isMatched(String name, String template) { private boolean isMatched(String name, String template) {
// check the validity of the domain name template. // check the validity of the domain name template.
try { try {
// Replacing wildcard character '*' with 'x' so as to check // Replacing wildcard character '*' with 'z' so as to check
// the domain name template validity. // the domain name template validity.
// //
// Using the checking implemented in SNIHostName // Using the checking implemented in SNIHostName
SNIHostName sni = new SNIHostName(template.replace('*', 'x')); SNIHostName sni = new SNIHostName(template.replace('*', 'z'));
} catch (IllegalArgumentException iae) { } catch (IllegalArgumentException iae) {
// It would be nice to add debug log if not matching. // It would be nice to add debug log if not matching.
return false; return false;
......
...@@ -4622,8 +4622,7 @@ png_image_free(png_imagep image) ...@@ -4622,8 +4622,7 @@ png_image_free(png_imagep image)
if (image != NULL && image->opaque != NULL && if (image != NULL && image->opaque != NULL &&
image->opaque->error_buf == NULL) image->opaque->error_buf == NULL)
{ {
/* Ignore errors here: */ png_image_free_function(image);
(void)png_safe_execute(image, png_image_free_function, image);
image->opaque = NULL; image->opaque = NULL;
} }
} }
......
...@@ -50,7 +50,13 @@ le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSu ...@@ -50,7 +50,13 @@ le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSu
le_uint16 altSetCount = SWAPW(alternateSetCount); le_uint16 altSetCount = SWAPW(alternateSetCount);
if (coverageIndex < altSetCount) { if (coverageIndex < altSetCount) {
Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]); const LEReferenceToArrayOf<Offset>
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> alternateSetTable(base, success, const LEReferenceTo<AlternateSetTable> alternateSetTable(base, success,
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset)); (const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
if (!LE_SUCCESS(success)) return 0; if (!LE_SUCCESS(success)) return 0;
......
...@@ -80,6 +80,9 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl ...@@ -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... // FIXME: We probably don't want to find a base glyph before a previous ligature...
GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/)); GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/));
LEGlyphID baseGlyph = findBaseGlyph(&baseIterator); LEGlyphID baseGlyph = findBaseGlyph(&baseIterator);
if (baseGlyph == 0xFFFF) {
return 0;
}
le_int32 baseCoverage = getBaseCoverage(base, (LEGlyphID) baseGlyph, success); le_int32 baseCoverage = getBaseCoverage(base, (LEGlyphID) baseGlyph, success);
LEReferenceTo<BaseArray> baseArray(base, success, (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset))); LEReferenceTo<BaseArray> baseArray(base, success, (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset)));
if(LE_FAILURE(success)) return 0; if(LE_FAILURE(success)) return 0;
......
...@@ -81,6 +81,9 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base ...@@ -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... // FIXME: we probably don't want to find a ligature before a previous base glyph...
GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/)); GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/));
LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator); LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator);
if (ligatureGlyph == 0xFFFF) {
return 0;
}
le_int32 ligatureCoverage = getBaseCoverage(base, (LEGlyphID) ligatureGlyph, success); le_int32 ligatureCoverage = getBaseCoverage(base, (LEGlyphID) ligatureGlyph, success);
LEReferenceTo<LigatureArray> ligatureArray(base, success, SWAPW(baseArrayOffset)); LEReferenceTo<LigatureArray> ligatureArray(base, success, SWAPW(baseArrayOffset));
if (LE_FAILURE(success)) { return 0; } if (LE_FAILURE(success)) { return 0; }
......
...@@ -81,6 +81,9 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl ...@@ -81,6 +81,9 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
GlyphIterator mark2Iterator(*glyphIterator); GlyphIterator mark2Iterator(*glyphIterator);
LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator); LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator);
if (mark2Glyph == 0xFFFF) {
return 0;
}
le_int32 mark2Coverage = getBaseCoverage(base, (LEGlyphID) mark2Glyph, success); le_int32 mark2Coverage = getBaseCoverage(base, (LEGlyphID) mark2Glyph, success);
LEReferenceTo<Mark2Array> mark2Array(base, success, (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset))); LEReferenceTo<Mark2Array> mark2Array(base, success, (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset)));
if(LE_FAILURE(success)) return 0; if(LE_FAILURE(success)) return 0;
......
...@@ -543,7 +543,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 ...@@ -543,7 +543,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
yAdjust += yKerning; yAdjust += yKerning;
#endif #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); xPlacement += adjustments->getXPlacement(base);
yPlacement += adjustments->getYPlacement(base); yPlacement += adjustments->getYPlacement(base);
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -95,7 +95,7 @@ public class Handler extends URLStreamHandler { ...@@ -95,7 +95,7 @@ public class Handler extends URLStreamHandler {
path = "\\\\" + host + path; path = "\\\\" + host + path;
File f = new File(path); File f = new File(path);
if (f.exists()) { if (f.exists()) {
return createFileURLConnection(url, f); return new UNCFileURLConnection(url, f, path);
} }
/* /*
......
/*
* 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;
}
}
...@@ -202,14 +202,17 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_PRNG_generateSeed ...@@ -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 * If length is negative and a seed is supplied, use it to re-seed the
* generator and return null. * generator. Return null whether a seed is supplied or not.
* If length is non-zero then generate a new seed according to the * If length is non-zero then generate a new seed according to the
* requested length and return the new seed. * requested length and return the new seed.
* If length is zero then overwrite the supplied seed with a new * If length is zero then overwrite the supplied seed with a new
* seed of the same length and return the seed. * seed of the same length and return the seed.
*/ */
if (length < 0) { if (length < 0) {
if (seed == NULL) {
__leave;
}
length = env->GetArrayLength(seed); length = env->GetArrayLength(seed);
if ((reseedBytes = env->GetByteArrayElements(seed, 0)) == NULL) { if ((reseedBytes = env->GetByteArrayElements(seed, 0)) == NULL) {
__leave; __leave;
......
/*
* 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<String, List<Integer>, 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<Integer> argument should be unmodifiable");
} catch (Exception e) {
}
return new AssertingOutOfBoundsException(message);
};
}
static BiFunction<String, List<Integer>, 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<Object[]> l = new ArrayList<>();
for (int index : VALUES) {
for (int length : VALUES) {
boolean withinBounds = index >= 0 &&
length >= 0 &&
index < length;
l.add(new Object[]{index, length, withinBounds});
}
}
return l.toArray(new Object[0][0]);
}
interface X {
int apply(int a, int b, int c);
}
@Test(dataProvider = "checkIndexProvider")
public void testCheckIndex(int index, int length, boolean withinBounds) {
List<Integer> list = Collections.unmodifiableList(Arrays.asList(new Integer[] { index, length }));
String expectedMessage = withinBounds
? null
: Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new).
apply("checkIndex", list).getMessage();
BiConsumer<Class<? extends RuntimeException>, IntSupplier> checker = (ec, s) -> {
try {
int rIndex = s.getAsInt();
if (!withinBounds)
fail(String.format(
"Index %d is out of bounds of [0, %d), but was reported to be within bounds", index, length));
assertEquals(rIndex, index);
}
catch (RuntimeException e) {
assertTrue(ec.isInstance(e));
if (withinBounds)
fail(String.format(
"Index %d is within bounds of [0, %d), but was reported to be out of bounds", index, length));
else
assertEquals(e.getMessage(), expectedMessage);
}
};
checker.accept(AssertingOutOfBoundsException.class,
() -> Preconditions.checkIndex(index, length,
assertingOutOfBounds(expectedMessage, "checkIndex", index, length)));
checker.accept(IndexOutOfBoundsException.class,
() -> Preconditions.checkIndex(index, length,
assertingOutOfBoundsReturnNull("checkIndex", index, length)));
checker.accept(IndexOutOfBoundsException.class,
() -> Preconditions.checkIndex(index, length, null));
checker.accept(ArrayIndexOutOfBoundsException.class,
() -> Preconditions.checkIndex(index, length,
Preconditions.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new)));
checker.accept(StringIndexOutOfBoundsException.class,
() -> Preconditions.checkIndex(index, length,
Preconditions.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new)));
}
@DataProvider
static Object[][] checkFromToIndexProvider() {
List<Object[]> l = new ArrayList<>();
for (int fromIndex : VALUES) {
for (int toIndex : VALUES) {
for (int length : VALUES) {
boolean withinBounds = fromIndex >= 0 &&
toIndex >= 0 &&
length >= 0 &&
fromIndex <= toIndex &&
toIndex <= length;
l.add(new Object[]{fromIndex, toIndex, length, withinBounds});
}
}
}
return l.toArray(new Object[0][0]);
}
@Test(dataProvider = "checkFromToIndexProvider")
public void testCheckFromToIndex(int fromIndex, int toIndex, int length, boolean withinBounds) {
List<Integer> list = Collections.unmodifiableList(Arrays.asList(new Integer[] { fromIndex, toIndex, length }));
String expectedMessage = withinBounds
? null
: Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new).
apply("checkFromToIndex", list).getMessage();
BiConsumer<Class<? extends RuntimeException>, IntSupplier> check = (ec, s) -> {
try {
int rIndex = s.getAsInt();
if (!withinBounds)
fail(String.format(
"Range [%d, %d) is out of bounds of [0, %d), but was reported to be withing bounds", fromIndex, toIndex, length));
assertEquals(rIndex, fromIndex);
}
catch (RuntimeException e) {
assertTrue(ec.isInstance(e));
if (withinBounds)
fail(String.format(
"Range [%d, %d) is within bounds of [0, %d), but was reported to be out of bounds", fromIndex, toIndex, length));
else
assertEquals(e.getMessage(), expectedMessage);
}
};
check.accept(AssertingOutOfBoundsException.class,
() -> Preconditions.checkFromToIndex(fromIndex, toIndex, length,
assertingOutOfBounds(expectedMessage, "checkFromToIndex", fromIndex, toIndex, length)));
check.accept(IndexOutOfBoundsException.class,
() -> Preconditions.checkFromToIndex(fromIndex, toIndex, length,
assertingOutOfBoundsReturnNull("checkFromToIndex", fromIndex, toIndex, length)));
check.accept(IndexOutOfBoundsException.class,
() -> Preconditions.checkFromToIndex(fromIndex, toIndex, length, null));
check.accept(ArrayIndexOutOfBoundsException.class,
() -> Preconditions.checkFromToIndex(fromIndex, toIndex, length,
Preconditions.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new)));
check.accept(StringIndexOutOfBoundsException.class,
() -> Preconditions.checkFromToIndex(fromIndex, toIndex, length,
Preconditions.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new)));
}
@DataProvider
static Object[][] checkFromIndexSizeProvider() {
List<Object[]> l = new ArrayList<>();
for (int fromIndex : VALUES) {
for (int size : VALUES) {
for (int length : VALUES) {
// Explicitly convert to long
long lFromIndex = fromIndex;
long lSize = size;
long lLength = length;
// Avoid overflow
long lToIndex = lFromIndex + lSize;
boolean withinBounds = lFromIndex >= 0L &&
lSize >= 0L &&
lLength >= 0L &&
lFromIndex <= lToIndex &&
lToIndex <= lLength;
l.add(new Object[]{fromIndex, size, length, withinBounds});
}
}
}
return l.toArray(new Object[0][0]);
}
@Test(dataProvider = "checkFromIndexSizeProvider")
public void testCheckFromIndexSize(int fromIndex, int size, int length, boolean withinBounds) {
List<Integer> list = Collections.unmodifiableList(Arrays.asList(new Integer[] { fromIndex, size, length }));
String expectedMessage = withinBounds
? null
: Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new).
apply("checkFromIndexSize", list).getMessage();
BiConsumer<Class<? extends RuntimeException>, IntSupplier> check = (ec, s) -> {
try {
int rIndex = s.getAsInt();
if (!withinBounds)
fail(String.format(
"Range [%d, %d + %d) is out of bounds of [0, %d), but was reported to be withing bounds", fromIndex, fromIndex, size, length));
assertEquals(rIndex, fromIndex);
}
catch (RuntimeException e) {
assertTrue(ec.isInstance(e));
if (withinBounds)
fail(String.format(
"Range [%d, %d + %d) is within bounds of [0, %d), but was reported to be out of bounds", fromIndex, fromIndex, size, length));
else
assertEquals(e.getMessage(), expectedMessage);
}
};
check.accept(AssertingOutOfBoundsException.class,
() -> Preconditions.checkFromIndexSize(fromIndex, size, length,
assertingOutOfBounds(expectedMessage, "checkFromIndexSize", fromIndex, size, length)));
check.accept(IndexOutOfBoundsException.class,
() -> Preconditions.checkFromIndexSize(fromIndex, size, length,
assertingOutOfBoundsReturnNull("checkFromIndexSize", fromIndex, size, length)));
check.accept(IndexOutOfBoundsException.class,
() -> Preconditions.checkFromIndexSize(fromIndex, size, length, null));
check.accept(ArrayIndexOutOfBoundsException.class,
() -> Preconditions.checkFromIndexSize(fromIndex, size, length,
Preconditions.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new)));
check.accept(StringIndexOutOfBoundsException.class,
() -> Preconditions.checkFromIndexSize(fromIndex, size, length,
Preconditions.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new)));
}
@Test
public void uniqueMessagesForCheckKinds() {
BiFunction<String, List<Integer>, IndexOutOfBoundsException> f =
Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new);
List<String> messages = new ArrayList<>();
List<Integer> arg1 = Collections.unmodifiableList(Arrays.asList(new Integer[] { -1 }));
List<Integer> arg2 = Collections.unmodifiableList(Arrays.asList(new Integer[] { -1, 0 }));
List<Integer> arg3 = Collections.unmodifiableList(Arrays.asList(new Integer[] { -1, 0, 0 }));
List<Integer> arg4 = Collections.unmodifiableList(Arrays.asList(new Integer[] { -1, 0, 0, 0 }));
// Exact arguments
messages.add(f.apply("checkIndex", arg2).getMessage());
messages.add(f.apply("checkFromToIndex", arg3).getMessage());
messages.add(f.apply("checkFromIndexSize", arg3).getMessage());
// Unknown check kind
messages.add(f.apply("checkUnknown", arg3).getMessage());
// Known check kind with more arguments
messages.add(f.apply("checkIndex", arg3).getMessage());
messages.add(f.apply("checkFromToIndex", arg4).getMessage());
messages.add(f.apply("checkFromIndexSize", arg4).getMessage());
// Known check kind with fewer arguments
messages.add(f.apply("checkIndex", arg1).getMessage());
messages.add(f.apply("checkFromToIndex", arg2).getMessage());
messages.add(f.apply("checkFromIndexSize", arg2).getMessage());
// Null arguments
messages.add(f.apply(null, null).getMessage());
messages.add(f.apply("checkNullArguments", null).getMessage());
messages.add(f.apply(null, arg1).getMessage());
assertEquals(messages.size(), messages.stream().distinct().count());
}
}
/*
* Copyright (c) 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
* 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
* @bug 8191073
* @summary Test verifies that when user tries to read image data from a
* tables-only image input stream it should through IIOException
* instead of throwing any other exception as per specification.
* @run main JpegTablesOnlyReadTest
*/
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
public class JpegTablesOnlyReadTest {
// JPEG input stream containing tables-only image
private static String inputImageBase64 = "/9j/4IAQSkZJRgABAQEASABIAAD"
+ "/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI//////////////////////"
+ "//////////////////////////////2wBDAVVaWnhpeOuCguv//////////////"
+ "///////////////////////////////////////////////////////////wAAR"
+ "CAAgACADASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECA//EACUQAQA"
+ "CAAUDBAMAAAAAAAAAAAEAAhESITGxQXKSA2Fi0SIyUf/EABYBAQEBAAAAAAAAAA"
+ "AAAAAAAAABA//EABcRAQEBAQAAAAAAAAAAAAAAAAEAESH/2gAMAwEAAhEDEQA/A"
+ "Nf2VW2OKaWTqnRhl97eb9wrs91uWPEBUX+EtmrssvvbzfuJWjVG2tg1svLLtgJ0"
+ "Uxwmd96d5zE7tVdnutyxm5JVoo0u6rpXHdWLP8PU8WIjtRuvVZN96d5zDP8AD1P"
+ "Fhre1Apc/Ida4RAdv/9k=";
public static void main(String[] args) throws IOException {
byte[] inputBytes = Base64.getDecoder().decode(inputImageBase64);
InputStream in = new ByteArrayInputStream(inputBytes);
// Read tables-only JPEG image
try {
ImageIO.read(in);
} catch (IIOException e) {
// do nothing we expect it to throw IIOException if it throws
// any other exception test will fail.
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册