| /* |
| * Copyright (c) 2008, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Chris Delahunt |
| // - Bug 318187 - NegativeArraySizeException on JCEEncryptor.decryptPassword() |
| package org.eclipse.persistence.testing.tests.simultaneous; |
| |
| import org.eclipse.persistence.testing.framework.AutoVerifyTestCase; |
| import org.eclipse.persistence.testing.framework.TestErrorException; |
| import org.eclipse.persistence.internal.security.JCEEncryptor; |
| |
| /** |
| * @author Chris Delahunt |
| * Test fix for 318187: |
| * java.lang.NegativeArraySizeException is thrown when threads concurrently access the |
| * JCEEncryptor.decrypt(password) |
| * |
| */ |
| public class ConcurrentDecryptionTest extends AutoVerifyTestCase { |
| //used to signal the threads to stop, accessed directly from the threads |
| public boolean run; |
| public Exception error; |
| |
| //number of concurrent threads to use |
| public int threadCount = 100; |
| //password to encrypt |
| public String password = "test1"; |
| //wait time for the error to occur |
| public int sleepTime = 8000; |
| |
| //accessed directly from the threads |
| private JCEEncryptor encryptor; |
| private String encryptedPassword; |
| |
| |
| @Override |
| protected void setup() throws Throwable { |
| encryptor = new JCEEncryptor(); |
| encryptedPassword = encryptor.encryptPassword(password); |
| } |
| |
| @Override |
| protected void test() throws Throwable { |
| run = true; |
| error = null; |
| try { |
| Thread[] thread = new Thread[threadCount]; |
| for(int i=0; i<threadCount; i++) { |
| thread[i]=new Thread(new Runner1(this)); |
| } |
| for(int i=0;i<threadCount; i++){ |
| thread[i].start(); |
| } |
| try { |
| Thread.sleep(sleepTime); |
| } catch (InterruptedException e) { |
| //exception could be ignored |
| e.printStackTrace(); |
| } |
| } finally { |
| //set the flag so started threads will end. |
| run = false; |
| } |
| } |
| |
| @Override |
| protected void verify() throws Throwable { |
| if (error!=null){ |
| throw new TestErrorException("error encountered: "+error, error); |
| } |
| } |
| |
| //runnable that repeatedly calls decryptPassword until the run flag is set to false |
| class Runner1 implements Runnable { |
| protected ConcurrentDecryptionTest concurrentDecryptionTest; |
| public Runner1(ConcurrentDecryptionTest concurrentDecryptionTest) { |
| this.concurrentDecryptionTest = concurrentDecryptionTest; |
| } |
| @Override |
| public void run() { |
| try { |
| while (concurrentDecryptionTest.run && (concurrentDecryptionTest.error == null) ){ |
| concurrentDecryptionTest.encryptor.decryptPassword(concurrentDecryptionTest.encryptedPassword); |
| } |
| } catch (Exception e){ |
| concurrentDecryptionTest.run = false; |
| concurrentDecryptionTest.error = e; |
| } |
| } |
| } |
| |
| } |