Java pattern causes stack overflow

I use a regular expression to extract key-value pairs from arbitrarily long input lines and run in the case when it causes a stack overflow for a long line with repeating patterns.

KV code coding looks something like this:

public static void parse(String input)
{
    String KV_REGEX = "((?:\"[^\"^ ]*\"|[^=,^ ])*) *= *((?:\"[^\"]*\"|[^=,^\\)^ ])*)";
    Pattern KV_PATTERN = Pattern.compile(KV_REGEX);

    Matcher matcher = KV_PATTERN.matcher(input);

    System.out.println("\nMatcher groups discovered:");

    while (matcher.find())
    {
        System.out.println(matcher.group(1) + ", " + matcher.group(2));
    }
}

Some dummy output examples:

    String input1 = "2012-08-09 09:10:25,521 INFO com.a.package.SomeClass - Everything working fine {name=CentOS, family=Linux, category=OS, version=2.6.x}";
    String input2 = "2012-08-09 blah blah 09:12:38,462 Log for the main thread, PID=5872, version=\"7.1.8.x\", build=1234567, other=done";

The call parse(input1)causes:

{name, CentOS
family, Linux
category, OS
version, 2.6.x}

The call parse(input2)causes:

PID, 5872
version, "7.1.8.x"
build, 1234567
other, done

This is normal (even with a little string processing needed for the first case). However, when trying to parse a very long (over 1000 characters) classpath string, the aforementioned class overflow occurs with the following exception (start):

Exception in thread "main" java.lang.StackOverflowError
    at java.util.regex.Pattern$BitClass.isSatisfiedBy(Pattern.java:2927)
    at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
    at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
    at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
    at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
    at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
    ...

The line is too long to enter here, but it has the following, easily reproducible and repeating structure:

java.class.path=/opt/files/any:/opt/files/any:/opt/files/any:/opt/files/any

, , :/opt/files/any . 90 ":/opt/files/any", , .

, KV_REGEX , ?

generic , , () .

, , -,

public void safeParse(String input)
{
    try
    {
        parse(input);
    }
    catch (StackOverflowError e) // Or even Throwable!
    {
        parse(input.substring(0, MAX_LENGTH));
    }
}

, , , - , .: -)

+5
1

, , , , . , :

public static void parse(String input) {
    String KV_REGEX = "(\"[^\" ]*\"|[^{=, ]*) *= *(\"[^\"]*\"|[^=,) }]*)";
    Pattern KV_PATTERN = Pattern.compile(KV_REGEX);

    Matcher matcher = KV_PATTERN.matcher(input);

    System.out.println("\nMatcher groups discovered:");

    while (matcher.find()) {
        System.out.println(matcher.group(1) + ", " + matcher.group(2));
    }
}

, :

(\"[^\" ]*\"|[^{=, ]*): , " s, {=,

*= *: , =,

(\"[^\"]*\"|[^=,) }]*): , " s, <<28 >

+3

All Articles