1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * @test
  28  * @bug 8158168
  29  * @summary Verifies that callers of StringUTF16 intrinsics throw array out of bounds exceptions.
  30  * @library /compiler/patches /test/lib
  31  * @build java.base/java.lang.Helper
  32  * @run main/othervm -Xbatch -XX:CompileThreshold=100 -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_getCharStringU,_putCharStringU compiler.intrinsics.string.TestStringUTF16IntrinsicRangeChecks
  33  * @run main/othervm -Xbatch -XX:CompileThreshold=100 -esa -ea -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_getCharStringU,_putCharStringU compiler.intrinsics.string.TestStringUTF16IntrinsicRangeChecks
  34  */
  35 package compiler.intrinsics.string;
  36 
  37 import java.lang.reflect.Field;
  38 import java.util.Arrays;
  39 
  40 public class TestStringUTF16IntrinsicRangeChecks {
  41 
  42     public static void main(String[] args) throws Exception {
  43         byte[] val = new byte[2];
  44         byte[] b4  = new byte[4];
  45         char[] c4  = new char[4];
  46         String s4 = new String(c4);
  47         byte[] valHigh = new byte[2];
  48         byte[] valLow  = new byte[2];
  49         Helper.putCharSB(valHigh, 0, Character.MIN_HIGH_SURROGATE);
  50         Helper.putCharSB(valLow,  0, Character.MIN_LOW_SURROGATE);
  51 
  52         for (int i = 0; i < 1000; ++i) {
  53             getChars((int)1234, -5, -5 + 4, val);
  54             getChars((int)1234, -1, -1 + 4, val);
  55             getChars((int)1234,  0,  0 + 4, val);
  56             getChars((int)1234,  1,  1 + 4, val);
  57 
  58             getChars((long)1234, -5, -5 + 4, val);
  59             getChars((long)1234, -1, -1 + 4, val);
  60             getChars((long)1234,  0,  0 + 4, val);
  61             getChars((long)1234,  1,  1 + 4, val);
  62 
  63             byte[] val2 = Arrays.copyOf(val, val.length);
  64             putCharSB(val2, -1, '!');
  65             putCharSB(val2,  1, '!');
  66 
  67             byte[] val4 = Arrays.copyOf(b4, b4.length);
  68             char[] c2  = new char[2];
  69             String s2 = new String(c2);
  70 
  71             putCharsSB(val4, -3, c2, 0, 2);
  72             putCharsSB(val4, -1, c2, 0, 2);
  73             putCharsSB(val4,  0, c4, 0, 4);
  74             putCharsSB(val4,  1, c2, 0, 2);
  75             putCharsSB(val4, -3, s2, 0, 2);
  76             putCharsSB(val4, -1, s2, 0, 2);
  77             putCharsSB(val4,  0, s4, 0, 4);
  78             putCharsSB(val4,  1, s2, 0, 2);
  79 
  80             codePointAtSB(valHigh, -1, 1);
  81             codePointAtSB(valHigh, -1, 2);
  82             codePointAtSB(valHigh,  0, 2);
  83             codePointAtSB(valHigh,  1, 2);
  84 
  85             codePointBeforeSB(valLow,  0);
  86             codePointBeforeSB(valLow, -1);
  87             codePointBeforeSB(valLow,  2);
  88 
  89             if (Helper.codePointCountSB(valHigh, 0, 1) != 1) {
  90                 throw new AssertionError("codePointCountSB");
  91             }
  92             if (Helper.codePointCountSB(valLow, 0, 1) != 1) {
  93                 throw new AssertionError("codePointCountSB");
  94             }
  95             codePointCountSB(valHigh, -1, 0);
  96             codePointCountSB(valHigh, -1, 2);
  97             codePointCountSB(valHigh,  0, 2);
  98 
  99             charAt(val, -1);
 100             charAt(val,  1);
 101 
 102             contentEquals(b4, val, -1);
 103             contentEquals(b4, val,  2);
 104             contentEquals(val, s4,  2);
 105             contentEquals(val, s4, -1);
 106 
 107             StringBuilder sb = new StringBuilder();
 108             sb.append((String)null).append(true).append(false);
 109             if (!sb.toString().equals("nulltruefalse")) {
 110                 throw new AssertionError("append");
 111             }
 112 
 113             putCharsAt(val2, -1, '1', '2', '3', '4');
 114             putCharsAt(val2,  0, '1', '2', '3', '4');
 115             putCharsAt(val2,  2, '1', '2', '3', '4');
 116             putCharsAt(val2, -1, '1', '2', '3', '4', '5');
 117             putCharsAt(val2,  0, '1', '2', '3', '4', '5');
 118             putCharsAt(val2,  2, '1', '2', '3', '4', '5');
 119 
 120             reverse(valHigh, -1);
 121             reverse(valHigh,  2);
 122             reverse(valLow,  -1);
 123             reverse(valLow,   2);
 124 
 125             byte[] d4 = new byte[4];
 126             inflate(b4, 0, d4, -1, 2);
 127             inflate(b4, 0, d4,  3, 2);
 128             inflate(b4, 0, d4,  4, 1);
 129 
 130             byte[] b0 = new byte[0];
 131             byte[] b1 = new byte[1];
 132             byte[] b2 = new byte[2];
 133             byte[] t1 = new byte[] {1};
 134             byte[] t2 = new byte[] {1, 2};
 135             byte[] t4 = new byte[] {1, 2, 3, 4};
 136             indexOf(b1,  1, t2,  1, 0);
 137             indexOf(b2,  1, t1,  1, 0);
 138             indexOf(b2,  2, t2,  1, 0);
 139             indexOf(b2,  1, t2,  2, 0);
 140             indexOf(b2, -1, t2,  1, 0);
 141             indexOf(b2,  1, t2, -1, 0);
 142             indexOf(b2,  1, t2,  1, 1);
 143 
 144             indexOfLatin1(b1,  1, t1,  1, 0);
 145             indexOfLatin1(b2,  2, t1,  1, 0);
 146             indexOfLatin1(b2,  1, b0,  1, 0);
 147             indexOfLatin1(b2,  1, t1,  2, 0);
 148             indexOfLatin1(b2, -1, t1,  1, 0);
 149             indexOfLatin1(b2,  2, t1,  1, 0);
 150             indexOfLatin1(b2,  1, t1, -1, 0);
 151             indexOfLatin1(b2,  1, t1,  2, 0);
 152 
 153             lastIndexOf(b1, t2, 1, 0);
 154             lastIndexOf(b2, t4, 2, 0);
 155             lastIndexOf(b2, t2, 1, 0);
 156             lastIndexOf(b2, t2, 1, 1);
 157 
 158             lastIndexOfLatin1(b1, t1, 1, 0);
 159             lastIndexOfLatin1(b2, t2, 2, 0);
 160             lastIndexOfLatin1(b2, t1, 1, 0);
 161             lastIndexOfLatin1(b2, t1, 1, 1);
 162         }
 163     }
 164 
 165     static void getChars(int i, int begin, int end, byte[] value) {
 166         try {
 167             Helper.getChars(i, begin, end, value);
 168             throw new AssertionError("getChars");
 169         } catch (IndexOutOfBoundsException io) {
 170         }
 171     }
 172 
 173     static void getChars(long l, int begin, int end, byte[] value) {
 174         try {
 175             Helper.getChars(l, begin, end, value);
 176             throw new AssertionError("getChars");
 177         } catch (IndexOutOfBoundsException io) {
 178         }
 179     }
 180 
 181     static void putCharSB(byte[] val, int index, int c) {
 182         try {
 183             Helper.putCharSB(val, index, c);
 184             throw new AssertionError("putCharSB");
 185         } catch (IndexOutOfBoundsException io) {
 186         }
 187     }
 188 
 189     static void putCharsSB(byte[] val, int index, char[] ca, int off, int end) {
 190         try {
 191             Helper.putCharsSB(val, index, ca, off, end);
 192             throw new AssertionError("putCharsSB");
 193         } catch (IndexOutOfBoundsException io) {
 194         }
 195     }
 196 
 197     static void putCharsSB(byte[] val, int index, CharSequence s, int off, int end) {
 198         try {
 199             Helper.putCharsSB(val, index, s, off, end);
 200             throw new AssertionError("putCharsSB");
 201         } catch (IndexOutOfBoundsException io) {
 202         }
 203     }
 204 
 205     static void codePointAtSB(byte[] val, int index, int end) {
 206         try {
 207             Helper.codePointAtSB(val, index, end);
 208             throw new AssertionError("codePointAtSB");
 209         } catch (IndexOutOfBoundsException io) {
 210         }
 211     }
 212 
 213     static void codePointBeforeSB(byte[] val, int index) {
 214         try {
 215             Helper.codePointBeforeSB(val, index);
 216             throw new AssertionError("codePointBeforeSB");
 217         } catch (IndexOutOfBoundsException io) {
 218         }
 219     }
 220 
 221     static void codePointCountSB(byte[] val, int beginIndex, int endIndex) {
 222         try {
 223             Helper.codePointCountSB(val, beginIndex, endIndex);
 224             throw new AssertionError("codePointCountSB");
 225         } catch (IndexOutOfBoundsException io) {
 226         }
 227     }
 228 
 229     static void charAt(byte[] v, int index) {
 230         try {
 231             Helper.charAt(v, index);
 232             throw new AssertionError("charAt");
 233         } catch (IndexOutOfBoundsException io) {
 234         }
 235     }
 236 
 237     static void contentEquals(byte[] v1, byte[] v2, int len) {
 238         try {
 239             Helper.contentEquals(v1, v2, len);
 240             throw new AssertionError("contentEquals");
 241         } catch (IndexOutOfBoundsException io) {
 242         }
 243     }
 244 
 245     static void contentEquals(byte[] v, CharSequence cs, int len) {
 246         try {
 247             Helper.contentEquals(v, cs, len);
 248             throw new AssertionError("contentEquals");
 249         } catch (IndexOutOfBoundsException io) {
 250         }
 251     }
 252 
 253     static void putCharsAt(byte[] v, int i, char c1, char c2, char c3, char c4) {
 254         try {
 255             Helper.putCharsAt(v, i, c1, c2, c3, c4);
 256             throw new AssertionError("putCharsAt");
 257         } catch (IndexOutOfBoundsException io) {
 258         }
 259     }
 260 
 261     static void putCharsAt(byte[] v, int i, char c1, char c2, char c3, char c4, char c5) {
 262         try {
 263             Helper.putCharsAt(v, i, c1, c2, c3, c4, c5);
 264             throw new AssertionError("putCharsAt");
 265         } catch (IndexOutOfBoundsException io) {
 266         }
 267     }
 268 
 269     static void reverse(byte[] v, int len) {
 270         try {
 271             Helper.reverse(v, len);
 272             throw new AssertionError("reverse");
 273         } catch (IndexOutOfBoundsException io) {
 274         }
 275     }
 276 
 277     static void inflate(byte[] v1, int o1, byte[] v2, int o2, int len) {
 278         try {
 279             Helper.inflate(v1, o1, v2, o2, len);
 280             throw new AssertionError("inflate");
 281         } catch (IndexOutOfBoundsException io) {
 282         }
 283     }
 284 
 285     static void indexOf(byte[] v1, int l1, byte[] v2, int l2, int from) {
 286         try {
 287             if (Helper.indexOf(v1, l1, v2, l2, from) != -1) {
 288                 throw new AssertionError("indexOf");
 289             }
 290         } catch (IndexOutOfBoundsException io) {
 291         }
 292     }
 293 
 294     static void lastIndexOf(byte[] v1, byte[] v2, int l2, int from) {
 295         try {
 296             if (Helper.lastIndexOf(v1, v2, l2, from) != -1) {
 297                 throw new AssertionError("lastIndexOf");
 298             }
 299         } catch (IndexOutOfBoundsException io) {
 300         }
 301     }
 302 
 303     static void indexOfLatin1(byte[] v1, int l1, byte[] v2, int l2, int from) {
 304         try {
 305             if (Helper.indexOfLatin1(v1, l1, v2, l2, from) != -1) {
 306                 throw new AssertionError("indexOfLatin1");
 307             }
 308         } catch (IndexOutOfBoundsException io) {
 309         }
 310     }
 311 
 312     static void lastIndexOfLatin1(byte[] v1, byte[] v2, int l2, int from) {
 313         try {
 314             if (Helper.lastIndexOfLatin1(v1, v2, l2, from) != -1) {
 315                 throw new AssertionError("lastIndexOfLatin1");
 316             }
 317         } catch (IndexOutOfBoundsException io) {
 318         }
 319     }
 320 }