|
1 | 1 | /*
|
2 |
| - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
4 | 4 | *
|
5 | 5 | * This code is free software; you can redistribute it and/or modify it
|
@@ -1090,6 +1090,10 @@ public static Pattern compile(String regex) {
|
1090 | 1090 | *
|
1091 | 1091 | * @throws PatternSyntaxException
|
1092 | 1092 | * If the expression's syntax is invalid
|
| 1093 | + * |
| 1094 | + * @implNote If {@link #CANON_EQ} is specified and the number of combining |
| 1095 | + * marks for any character is too large, an {@link java.lang.OutOfMemoryError} |
| 1096 | + * is thrown. |
1093 | 1097 | */
|
1094 | 1098 | public static Pattern compile(String regex, int flags) {
|
1095 | 1099 | return new Pattern(regex, flags);
|
@@ -1123,6 +1127,13 @@ public String toString() {
|
1123 | 1127 | * The character sequence to be matched
|
1124 | 1128 | *
|
1125 | 1129 | * @return A new matcher for this pattern
|
| 1130 | + * |
| 1131 | + * @implNote When a {@link Pattern} is deserialized, compilation is deferred |
| 1132 | + * until a direct or indirect invocation of this method. Thus, if a |
| 1133 | + * deserialized pattern has {@link #CANON_EQ} among its flags and the number |
| 1134 | + * of combining marks for any character is too large, an |
| 1135 | + * {@link java.lang.OutOfMemoryError} is thrown, |
| 1136 | + * as in {@link #compile(String, int)}. |
1126 | 1137 | */
|
1127 | 1138 | public Matcher matcher(CharSequence input) {
|
1128 | 1139 | if (!compiled) {
|
@@ -1596,14 +1607,30 @@ private static String[] producePermutations(String input) {
|
1596 | 1607 | return result;
|
1597 | 1608 | }
|
1598 | 1609 |
|
1599 |
| - int length = 1; |
| 1610 | + /* |
| 1611 | + * Since |
| 1612 | + * 12! = 479_001_600 < Integer.MAX_VALUE |
| 1613 | + * 13! = 6_227_020_800 > Integer.MAX_VALUE |
| 1614 | + * the computation of n! using int arithmetic will overflow iff |
| 1615 | + * n < 0 or n > 12 |
| 1616 | + * |
| 1617 | + * Here, nCodePoints! is computed in the next for-loop below. |
| 1618 | + * As nCodePoints >= 0, the computation overflows iff nCodePoints > 12. |
| 1619 | + * In that case, throw OOME to simulate length > Integer.MAX_VALUE. |
| 1620 | + */ |
1600 | 1621 | int nCodePoints = countCodePoints(input);
|
1601 |
| - for(int x=1; x<nCodePoints; x++) |
1602 |
| - length = length * (x+1); |
| 1622 | + if (nCodePoints > 12) { |
| 1623 | + throw new OutOfMemoryError("Pattern too complex"); |
| 1624 | + } |
1603 | 1625 |
|
| 1626 | + /* Compute length = nCodePoints! */ |
| 1627 | + int length = 1; |
| 1628 | + for (int x = 2; x <= nCodePoints; ++x) { |
| 1629 | + length *= x; |
| 1630 | + } |
1604 | 1631 | String[] temp = new String[length];
|
1605 | 1632 |
|
1606 |
| - int combClass[] = new int[nCodePoints]; |
| 1633 | + int[] combClass = new int[nCodePoints]; |
1607 | 1634 | for(int x=0, i=0; x<nCodePoints; x++) {
|
1608 | 1635 | int c = Character.codePointAt(input, i);
|
1609 | 1636 | combClass[x] = getClass(c);
|
|
0 commit comments