Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: xml highlighter gives StackOverflowError #1212

Closed
PavelTurk opened this issue Nov 13, 2023 · 2 comments
Closed

Question: xml highlighter gives StackOverflowError #1212

PavelTurk opened this issue Nov 13, 2023 · 2 comments

Comments

@PavelTurk
Copy link
Contributor

PavelTurk commented Nov 13, 2023

This is my highlighter:

public class XmlHighlighter {

    private static final Pattern XML_TAG = Pattern.compile("(?<ELEMENT>(</?\\h*)(\\w+)([^<>]*)(\\h*/?>))"
    		+"|(?<COMMENT><!--(.|\\v)+?-->)");

    private static final Pattern ATTRIBUTES = Pattern.compile("(\\w+\\h*)(=)(\\h*\"[^\"]+\")");

    private static final int GROUP_OPEN_BRACKET = 2;

    private static final int GROUP_ELEMENT_NAME = 3;

    private static final int GROUP_ATTRIBUTES_SECTION = 4;

    private static final int GROUP_CLOSE_BRACKET = 5;

    private static final int GROUP_ATTRIBUTE_NAME = 1;

    private static final int GROUP_EQUAL_SYMBOL = 2;

    private static final int GROUP_ATTRIBUTE_VALUE = 3;

    public StyleSpans<Collection<String>> computeHighlighting(String text) {
        Matcher matcher = XML_TAG.matcher(text);
        int lastKwEnd = 0;
        StyleSpansBuilder<Collection<String>> spansBuilder = new StyleSpansBuilder<>();
        while(matcher.find()) {
            spansBuilder.add(Collections.emptyList(), matcher.start() - lastKwEnd);
            if(matcher.group("COMMENT") != null) {
                    spansBuilder.add(Collections.singleton("comment"), matcher.end() - matcher.start());
            } else {
                if(matcher.group("ELEMENT") != null) {
                    String attributesText = matcher.group(GROUP_ATTRIBUTES_SECTION);
                    spansBuilder.add(Collections.singleton("tagmark"),
                            matcher.end(GROUP_OPEN_BRACKET) - matcher.start(GROUP_OPEN_BRACKET));
                    spansBuilder.add(Collections.singleton("anytag"),
                            matcher.end(GROUP_ELEMENT_NAME) - matcher.end(GROUP_OPEN_BRACKET));
                    if(!attributesText.isEmpty()) {
                        lastKwEnd = 0;
                        Matcher amatcher = ATTRIBUTES.matcher(attributesText);
                        while(amatcher.find()) {
                            spansBuilder.add(Collections.emptyList(), amatcher.start() - lastKwEnd);
                            spansBuilder.add(Collections.singleton("attribute"),
                                    amatcher.end(GROUP_ATTRIBUTE_NAME) - amatcher.start(GROUP_ATTRIBUTE_NAME));
                            spansBuilder.add(Collections.singleton("tagmark"),
                                    amatcher.end(GROUP_EQUAL_SYMBOL) - amatcher.end(GROUP_ATTRIBUTE_NAME));
                            spansBuilder.add(Collections.singleton("avalue"),
                                    amatcher.end(GROUP_ATTRIBUTE_VALUE) - amatcher.end(GROUP_EQUAL_SYMBOL));
                            lastKwEnd = amatcher.end();
                        }
                        if(attributesText.length() > lastKwEnd) {
                            spansBuilder.add(Collections.emptyList(), attributesText.length() - lastKwEnd);
                        }
                    }
                    lastKwEnd = matcher.end(GROUP_ATTRIBUTES_SECTION);
                    spansBuilder.add(Collections.singleton("tagmark"), matcher.end(GROUP_CLOSE_BRACKET) - lastKwEnd);
                }
            }
            lastKwEnd = matcher.end();
        }
        spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd);
        return spansBuilder.create();
    }

}

This is xml code that breaks my highlighter:

<!--            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-all</artifactId>
                <version>1.11.0</version>
                <scope>compile</scope>
                <exclusions>
                    <exclusion>
                        <groupId>com.google.code.findbugs</groupId>
                        <artifactId>jsr305</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-config-core</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-aspectj</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-cache</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-core</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-crypto-cipher</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-crypto-core</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-crypto-hash</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-ehcache</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-event</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-quartz</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-spring</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-lang</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-hazelcast</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-guice</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-web</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-config-ogdl</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
             SHIRO ALL doesn't include dependencies, so we add them manually 
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-jaxrs</artifactId>
                <version>1.11.0</version>
                <scope>compile</scope>
                <exclusions>
                    <exclusion>
                        <groupId>com.google.code.findbugs</groupId>
                        <artifactId>jsr305</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-config-core</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-aspectj</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-cache</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-core</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-crypto-cipher</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-crypto-core</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-crypto-hash</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-ehcache</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-event</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-quartz</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-spring</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-lang</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-hazelcast</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-guice</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-web</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.shiro</groupId>
                        <artifactId>shiro-config-ogdl</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>javax.ws.rs</groupId>
                        <artifactId>javax.ws.rs-api</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>commons-beanutils</groupId>
                <artifactId>commons-beanutils</artifactId>
                <version>1.9.4</version>
            </dependency>-->

And this is what I have:

2023-11-13 23:53:24.310 [ERROR] [JavaFX Application Thread] pk.kit.fx.FxPlatform - Error in FxApplication java.lang.StackOverflowError
	at java.base/java.util.regex.Pattern$Branch.match(Pattern.java:4914)
	at java.base/java.util.regex.Pattern$GroupHead.match(Pattern.java:4969)
	at java.base/java.util.regex.Pattern$LazyLoop.match(Pattern.java:5146)
	at java.base/java.util.regex.Pattern$GroupTail.match(Pattern.java:5000)
	at java.base/java.util.regex.Pattern$BranchConn.match(Pattern.java:4878)
	at java.base/java.util.regex.Pattern$CharProperty.match(Pattern.java:4110)
	at java.base/java.util.regex.Pattern$Branch.match(Pattern.java:4914)
	at java.base/java.util.regex.Pattern$GroupHead.match(Pattern.java:4969)
	at java.base/java.util.regex.Pattern$LazyLoop.match(Pattern.java:5146)
	at java.base/java.util.regex.Pattern$GroupTail.match(Pattern.java:5000)
	at java.base/java.util.regex.Pattern$BranchConn.match(Pattern.java:4878)
	at java.base/java.util.regex.Pattern$CharProperty.match(Pattern.java:4110)
	at java.base/java.util.regex.Pattern$Branch.match(Pattern.java:4914)
	at java.base/java.util.regex.Pattern$GroupHead.match(Pattern.java:4969)
	at java.base/java.util.regex.Pattern$LazyLoop.match(Pattern.java:5146)
	at java.base/java.util.regex.Pattern$GroupTail.match(Pattern.java:5000)
	at java.base/java.util.regex.Pattern$BranchConn.match(Pattern.java:4878)
	at java.base/java.util.regex.Pattern$CharProperty.match(Pattern.java:4110)
	at java.base/java.util.regex.Pattern$Branch.match(Pattern.java:4914)
	at java.base/java.util.regex.Pattern$GroupHead.match(Pattern.java:4969)
	at java.base/java.util.regex.Pattern$LazyLoop.match(Pattern.java:5146)

Could anyone say how to fix it?

@Jugen
Copy link
Collaborator

Jugen commented Nov 14, 2023

If you haven't done so already, I think you're likely to get a helpful response posting on a forum specializing in Java regex.

@PavelTurk
Copy link
Contributor Author

PavelTurk commented Nov 14, 2023

I found solution here - https://superuser.com/a/1153242/491751. So, final pattern that worked for me is

 private static final Pattern XML_TAG = Pattern.compile("(?<ELEMENT>(</?\\h*)(\\w+)([^<>]*)(\\h*/?>))"
                +"|(?<COMMENT><!--[\\s\\S\\n]*?-->)");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants