8187089: StringConcatFactory.makeConcat & makeConcatWithConstants should throw StringConcatException if parameter slot count is over 200
authormchung
Thu, 26 Oct 2017 16:57:35 -0700
changeset 47461 60a5d9c77c4c
parent 47460 b6d959fae9ef
child 47462 b1b37e21fb6f
8187089: StringConcatFactory.makeConcat & makeConcatWithConstants should throw StringConcatException if parameter slot count is over 200 Reviewed-by: rriggs, shade
src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java
test/jdk/java/lang/invoke/StringConcatFactory/BasicTest.java
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Thu Oct 26 11:08:31 2017 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Thu Oct 26 16:57:35 2017 -0700
@@ -398,8 +398,8 @@
      * <p>Then the following linkage invariants must hold:
      *
      * <ul>
-     *     <li>The parameter count in {@code concatType} is less than or equal to 200</li>
-     *
+     *     <li>The number of parameter slots in {@code concatType} is
+     *         less than or equal to 200</li>
      *     <li>The return type in {@code concatType} is assignable from {@link java.lang.String}</li>
      * </ul>
      *
@@ -487,8 +487,8 @@
      * <p>Then the following linkage invariants must hold:
      *
      * <ul>
-     *   <li>The parameter count in {@code concatType} is less than or equal to
-     *   200</li>
+     *   <li>The number of parameter slots in {@code concatType} is less than
+     *       or equal to 200</li>
      *
      *   <li>The parameter count in {@code concatType} equals to number of \1 tags
      *   in {@code recipe}</li>
@@ -613,9 +613,9 @@
                             concatType.returnType());
         }
 
-        if (concatType.parameterCount() > MAX_INDY_CONCAT_ARG_SLOTS) {
+        if (concatType.parameterSlotCount() > MAX_INDY_CONCAT_ARG_SLOTS) {
             throw new StringConcatException("Too many concat argument slots: " +
-                    concatType.parameterCount() +
+                    concatType.parameterSlotCount() +
                     ", can only accept " +
                     MAX_INDY_CONCAT_ARG_SLOTS);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/StringConcatFactory/BasicTest.java	Thu Oct 26 16:57:35 2017 -0700
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ *
+ * 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 8187089
+ * @run main BasicTest
+ */
+
+import java.lang.invoke.*;
+import java.util.Arrays;
+
+public class BasicTest {
+    static final int MAX_PARAM_SLOTS = 200;
+    static int exceedMaxParamSlots = 0;
+    public static void main(String[] args) throws Throwable {
+        int expectionTestCases = 0;
+
+        Class<?>[] types = new Class<?>[200];
+        Arrays.fill(types, int.class);
+        test(MethodType.methodType(String.class, types));
+
+        types = new Class<?>[100];
+        Arrays.fill(types, long.class);
+        test(MethodType.methodType(String.class, types));
+
+        // test cases exceeding 200 parameter slots
+        expectionTestCases++;
+        types = new Class<?>[101];
+        Arrays.fill(types, 0, 50, long.class);
+        Arrays.fill(types, 50, 100, double.class);
+        types[100] = int.class;
+        test(MethodType.methodType(String.class, types));
+
+        expectionTestCases++;
+        types = new Class<?>[201];
+        Arrays.fill(types, int.class);
+        test(MethodType.methodType(String.class, types));
+
+        if (exceedMaxParamSlots != expectionTestCases) {
+            throw new RuntimeException("expected one test case exceeding 200 param slots");
+        }
+    }
+
+    /**
+     * Tests if StringConcatException is thrown if the given concatType
+     * has more than 200 parameter slots
+     */
+    static void test(MethodType concatType) throws StringConcatException {
+        String recipe = "";
+        int slots = 0;
+        for (Class<?> c : concatType.parameterList()) {
+            recipe += "\1";
+            slots++;
+            if (c == double.class || c == long.class) {
+                slots++;
+            }
+        }
+        if (slots > MAX_PARAM_SLOTS) {
+            exceedMaxParamSlots++;
+        }
+        System.out.format("Test %s parameter slots%n", slots);
+        try {
+            StringConcatFactory.makeConcat(MethodHandles.lookup(), "name", concatType);
+            if (slots > MAX_PARAM_SLOTS) {
+                throw new RuntimeException("StringConcatException not thrown");
+            }
+        } catch (StringConcatException e) {
+            if (slots <= MAX_PARAM_SLOTS) throw e;
+        }
+
+        try {
+            StringConcatFactory.makeConcatWithConstants(MethodHandles.lookup(), "name",
+                                                        concatType, recipe);
+            if (slots > MAX_PARAM_SLOTS) {
+                throw new RuntimeException("StringConcatException not thrown");
+            }
+        } catch (StringConcatException e) {
+            if (slots <= MAX_PARAM_SLOTS) throw e;
+        }
+    }
+}