8224789: Parsing repetition count in regex does not detect numeric overflow
Reviewed-by: rriggs, bchristi
This commit is contained in:
parent
051b4e2963
commit
f5e2916507
@ -3271,28 +3271,33 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
|
||||
case '+':
|
||||
return curly(prev, 1);
|
||||
case '{':
|
||||
ch = temp[cursor+1];
|
||||
ch = skip();
|
||||
if (ASCII.isDigit(ch)) {
|
||||
skip();
|
||||
int cmin = 0;
|
||||
do {
|
||||
cmin = cmin * 10 + (ch - '0');
|
||||
} while (ASCII.isDigit(ch = read()));
|
||||
int cmax = cmin;
|
||||
if (ch == ',') {
|
||||
ch = read();
|
||||
cmax = MAX_REPS;
|
||||
if (ch != '}') {
|
||||
cmax = 0;
|
||||
while (ASCII.isDigit(ch)) {
|
||||
cmax = cmax * 10 + (ch - '0');
|
||||
ch = read();
|
||||
int cmin = 0, cmax;
|
||||
try {
|
||||
do {
|
||||
cmin = Math.addExact(Math.multiplyExact(cmin, 10),
|
||||
ch - '0');
|
||||
} while (ASCII.isDigit(ch = read()));
|
||||
cmax = cmin;
|
||||
if (ch == ',') {
|
||||
ch = read();
|
||||
cmax = MAX_REPS;
|
||||
if (ch != '}') {
|
||||
cmax = 0;
|
||||
while (ASCII.isDigit(ch)) {
|
||||
cmax = Math.addExact(Math.multiplyExact(cmax, 10),
|
||||
ch - '0');
|
||||
ch = read();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ArithmeticException ae) {
|
||||
throw error("Illegal repetition range");
|
||||
}
|
||||
if (ch != '}')
|
||||
throw error("Unclosed counted closure");
|
||||
if (((cmin) | (cmax) | (cmax - cmin)) < 0)
|
||||
if (cmax < cmin)
|
||||
throw error("Illegal repetition range");
|
||||
Curly curly;
|
||||
ch = peek();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2019, 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
|
||||
@ -35,7 +35,7 @@
|
||||
* 8027645 8035076 8039124 8035975 8074678 6854417 8143854 8147531 7071819
|
||||
* 8151481 4867170 7080302 6728861 6995635 6736245 4916384 6328855 6192895
|
||||
* 6345469 6988218 6693451 7006761 8140212 8143282 8158482 8176029 8184706
|
||||
* 8194667 8197462 8184692 8221431
|
||||
* 8194667 8197462 8184692 8221431 8224789
|
||||
*
|
||||
* @library /test/lib
|
||||
* @library /lib/testlibrary/java/lang
|
||||
@ -44,15 +44,28 @@
|
||||
* @key randomness
|
||||
*/
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Scanner;
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.util.*;
|
||||
import java.nio.CharBuffer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.MatchResult;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
|
||||
/**
|
||||
@ -171,6 +184,7 @@ public class RegExTest {
|
||||
grapheme();
|
||||
expoBacktracking();
|
||||
invalidGroupName();
|
||||
illegalRepetitionRange();
|
||||
|
||||
if (failure) {
|
||||
throw new
|
||||
@ -4932,4 +4946,31 @@ public class RegExTest {
|
||||
}
|
||||
report("Invalid capturing group names");
|
||||
}
|
||||
|
||||
private static void illegalRepetitionRange() {
|
||||
// huge integers > (2^31 - 1)
|
||||
String n = BigInteger.valueOf(1L << 32)
|
||||
.toString();
|
||||
String m = BigInteger.valueOf(1L << 31)
|
||||
.add(new BigInteger(80, generator))
|
||||
.toString();
|
||||
for (String rep : List.of("", "x", ".", ",", "-1", "2,1",
|
||||
n, n + ",", "0," + n, n + "," + m, m, m + ",", "0," + m)) {
|
||||
String pat = ".{" + rep + "}";
|
||||
try {
|
||||
Pattern.compile(pat);
|
||||
failCount++;
|
||||
System.out.println("Expected to fail. Pattern: " + pat);
|
||||
} catch (PatternSyntaxException e) {
|
||||
if (!e.getMessage().startsWith("Illegal repetition")) {
|
||||
failCount++;
|
||||
System.out.println("Unexpected error message: " + e.getMessage());
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
failCount++;
|
||||
System.out.println("Unexpected exception: " + t);
|
||||
}
|
||||
}
|
||||
report("illegalRepetitionRange");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user