/* * Copyright (c) 2017, 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. */ /* * @test * @bug 8158168 * @summary Verifies that callers of StringUTF16 intrinsics throw array out of bounds exceptions. * @library /compiler/patches /test/lib * @build java.base/java.lang.Helper * @run main/othervm -Xbatch -XX:CompileThreshold=100 -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_getCharStringU,_putCharStringU compiler.intrinsics.string.TestStringUTF16IntrinsicRangeChecks * @run main/othervm -Xbatch -XX:CompileThreshold=100 -esa -ea -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_getCharStringU,_putCharStringU compiler.intrinsics.string.TestStringUTF16IntrinsicRangeChecks */ package compiler.intrinsics.string; import java.lang.reflect.Field; import java.util.Arrays; public class TestStringUTF16IntrinsicRangeChecks { public static void main(String[] args) throws Exception { byte[] val = new byte[2]; byte[] b4 = new byte[4]; char[] c4 = new char[4]; String s4 = new String(c4); byte[] valHigh = new byte[2]; byte[] valLow = new byte[2]; Helper.putCharSB(valHigh, 0, Character.MIN_HIGH_SURROGATE); Helper.putCharSB(valLow, 0, Character.MIN_LOW_SURROGATE); for (int i = 0; i < 1000; ++i) { getChars((int)1234, -5, -5 + 4, val); getChars((int)1234, -1, -1 + 4, val); getChars((int)1234, 0, 0 + 4, val); getChars((int)1234, 1, 1 + 4, val); getChars((long)1234, -5, -5 + 4, val); getChars((long)1234, -1, -1 + 4, val); getChars((long)1234, 0, 0 + 4, val); getChars((long)1234, 1, 1 + 4, val); byte[] val2 = Arrays.copyOf(val, val.length); putCharSB(val2, -1, '!'); putCharSB(val2, 1, '!'); byte[] val4 = Arrays.copyOf(b4, b4.length); char[] c2 = new char[2]; String s2 = new String(c2); putCharsSB(val4, -3, c2, 0, 2); putCharsSB(val4, -1, c2, 0, 2); putCharsSB(val4, 0, c4, 0, 4); putCharsSB(val4, 1, c2, 0, 2); putCharsSB(val4, -3, s2, 0, 2); putCharsSB(val4, -1, s2, 0, 2); putCharsSB(val4, 0, s4, 0, 4); putCharsSB(val4, 1, s2, 0, 2); codePointAtSB(valHigh, -1, 1); codePointAtSB(valHigh, -1, 2); codePointAtSB(valHigh, 0, 2); codePointAtSB(valHigh, 1, 2); codePointBeforeSB(valLow, 0); codePointBeforeSB(valLow, -1); codePointBeforeSB(valLow, 2); if (Helper.codePointCountSB(valHigh, 0, 1) != 1) { throw new AssertionError("codePointCountSB"); } if (Helper.codePointCountSB(valLow, 0, 1) != 1) { throw new AssertionError("codePointCountSB"); } codePointCountSB(valHigh, -1, 0); codePointCountSB(valHigh, -1, 2); codePointCountSB(valHigh, 0, 2); charAt(val, -1); charAt(val, 1); contentEquals(b4, val, -1); contentEquals(b4, val, 2); contentEquals(val, s4, 2); contentEquals(val, s4, -1); StringBuilder sb = new StringBuilder(); sb.append((String)null).append(true).append(false); if (!sb.toString().equals("nulltruefalse")) { throw new AssertionError("append"); } putCharsAt(val2, -1, '1', '2', '3', '4'); putCharsAt(val2, 0, '1', '2', '3', '4'); putCharsAt(val2, 2, '1', '2', '3', '4'); putCharsAt(val2, -1, '1', '2', '3', '4', '5'); putCharsAt(val2, 0, '1', '2', '3', '4', '5'); putCharsAt(val2, 2, '1', '2', '3', '4', '5'); reverse(valHigh, -1); reverse(valHigh, 2); reverse(valLow, -1); reverse(valLow, 2); byte[] d4 = new byte[4]; inflate(b4, 0, d4, -1, 2); inflate(b4, 0, d4, 3, 2); inflate(b4, 0, d4, 4, 1); byte[] b0 = new byte[0]; byte[] b1 = new byte[1]; byte[] b2 = new byte[2]; byte[] t1 = new byte[] {1}; byte[] t2 = new byte[] {1, 2}; byte[] t4 = new byte[] {1, 2, 3, 4}; indexOf(b1, 1, t2, 1, 0); indexOf(b2, 1, t1, 1, 0); indexOf(b2, 2, t2, 1, 0); indexOf(b2, 1, t2, 2, 0); indexOf(b2, -1, t2, 1, 0); indexOf(b2, 1, t2, -1, 0); indexOf(b2, 1, t2, 1, 1); indexOfLatin1(b1, 1, t1, 1, 0); indexOfLatin1(b2, 2, t1, 1, 0); indexOfLatin1(b2, 1, b0, 1, 0); indexOfLatin1(b2, 1, t1, 2, 0); indexOfLatin1(b2, -1, t1, 1, 0); indexOfLatin1(b2, 2, t1, 1, 0); indexOfLatin1(b2, 1, t1, -1, 0); indexOfLatin1(b2, 1, t1, 2, 0); lastIndexOf(b1, t2, 1, 0); lastIndexOf(b2, t4, 2, 0); lastIndexOf(b2, t2, 1, 0); lastIndexOf(b2, t2, 1, 1); lastIndexOfLatin1(b1, t1, 1, 0); lastIndexOfLatin1(b2, t2, 2, 0); lastIndexOfLatin1(b2, t1, 1, 0); lastIndexOfLatin1(b2, t1, 1, 1); } } static void getChars(int i, int begin, int end, byte[] value) { try { Helper.getChars(i, begin, end, value); throw new AssertionError("getChars"); } catch (IndexOutOfBoundsException io) { } } static void getChars(long l, int begin, int end, byte[] value) { try { Helper.getChars(l, begin, end, value); throw new AssertionError("getChars"); } catch (IndexOutOfBoundsException io) { } } static void putCharSB(byte[] val, int index, int c) { try { Helper.putCharSB(val, index, c); throw new AssertionError("putCharSB"); } catch (IndexOutOfBoundsException io) { } } static void putCharsSB(byte[] val, int index, char[] ca, int off, int end) { try { Helper.putCharsSB(val, index, ca, off, end); throw new AssertionError("putCharsSB"); } catch (IndexOutOfBoundsException io) { } } static void putCharsSB(byte[] val, int index, CharSequence s, int off, int end) { try { Helper.putCharsSB(val, index, s, off, end); throw new AssertionError("putCharsSB"); } catch (IndexOutOfBoundsException io) { } } static void codePointAtSB(byte[] val, int index, int end) { try { Helper.codePointAtSB(val, index, end); throw new AssertionError("codePointAtSB"); } catch (IndexOutOfBoundsException io) { } } static void codePointBeforeSB(byte[] val, int index) { try { Helper.codePointBeforeSB(val, index); throw new AssertionError("codePointBeforeSB"); } catch (IndexOutOfBoundsException io) { } } static void codePointCountSB(byte[] val, int beginIndex, int endIndex) { try { Helper.codePointCountSB(val, beginIndex, endIndex); throw new AssertionError("codePointCountSB"); } catch (IndexOutOfBoundsException io) { } } static void charAt(byte[] v, int index) { try { Helper.charAt(v, index); throw new AssertionError("charAt"); } catch (IndexOutOfBoundsException io) { } } static void contentEquals(byte[] v1, byte[] v2, int len) { try { Helper.contentEquals(v1, v2, len); throw new AssertionError("contentEquals"); } catch (IndexOutOfBoundsException io) { } } static void contentEquals(byte[] v, CharSequence cs, int len) { try { Helper.contentEquals(v, cs, len); throw new AssertionError("contentEquals"); } catch (IndexOutOfBoundsException io) { } } static void putCharsAt(byte[] v, int i, char c1, char c2, char c3, char c4) { try { Helper.putCharsAt(v, i, c1, c2, c3, c4); throw new AssertionError("putCharsAt"); } catch (IndexOutOfBoundsException io) { } } static void putCharsAt(byte[] v, int i, char c1, char c2, char c3, char c4, char c5) { try { Helper.putCharsAt(v, i, c1, c2, c3, c4, c5); throw new AssertionError("putCharsAt"); } catch (IndexOutOfBoundsException io) { } } static void reverse(byte[] v, int len) { try { Helper.reverse(v, len); throw new AssertionError("reverse"); } catch (IndexOutOfBoundsException io) { } } static void inflate(byte[] v1, int o1, byte[] v2, int o2, int len) { try { Helper.inflate(v1, o1, v2, o2, len); throw new AssertionError("inflate"); } catch (IndexOutOfBoundsException io) { } } static void indexOf(byte[] v1, int l1, byte[] v2, int l2, int from) { try { if (Helper.indexOf(v1, l1, v2, l2, from) != -1) { throw new AssertionError("indexOf"); } } catch (IndexOutOfBoundsException io) { } } static void lastIndexOf(byte[] v1, byte[] v2, int l2, int from) { try { if (Helper.lastIndexOf(v1, v2, l2, from) != -1) { throw new AssertionError("lastIndexOf"); } } catch (IndexOutOfBoundsException io) { } } static void indexOfLatin1(byte[] v1, int l1, byte[] v2, int l2, int from) { try { if (Helper.indexOfLatin1(v1, l1, v2, l2, from) != -1) { throw new AssertionError("indexOfLatin1"); } } catch (IndexOutOfBoundsException io) { } } static void lastIndexOfLatin1(byte[] v1, byte[] v2, int l2, int from) { try { if (Helper.lastIndexOfLatin1(v1, v2, l2, from) != -1) { throw new AssertionError("lastIndexOfLatin1"); } } catch (IndexOutOfBoundsException io) { } } }