Skip to content

Commit edd5bfc

Browse files
authored
avoid quadratic backtracking in Server name pattern (#2489)
1 parent f5ecba7 commit edd5bfc

2 files changed

Lines changed: 18 additions & 1 deletion

File tree

src/main/java/net/sf/jsqlparser/schema/Server.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
public final class Server implements MultiPartName {
1515

1616
public static final Pattern SERVER_PATTERN =
17-
Pattern.compile("\\[([^\\]]+?)(?:\\\\([^\\]]+))?\\]");
17+
Pattern.compile("\\[([^\\]\\\\]+)(?:\\\\([^\\]]+))?\\]");
1818

1919
private String serverName;
2020

src/test/java/net/sf/jsqlparser/schema/ServerTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,27 @@
1010
package net.sf.jsqlparser.schema;
1111

1212
import static org.junit.jupiter.api.Assertions.assertEquals;
13+
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
14+
15+
import java.time.Duration;
1316
import org.junit.jupiter.api.Test;
1417

1518
public class ServerTest {
1619

20+
@Test
21+
public void testCraftedServerNameDoesNotBacktrack() throws Exception {
22+
final StringBuilder sb = new StringBuilder("[");
23+
for (int i = 0; i < 40000; i++) {
24+
sb.append("a\\");
25+
}
26+
final String crafted = sb.toString();
27+
28+
// an unterminated bracketed name full of backslashes used to backtrack quadratically
29+
final Server server = assertTimeoutPreemptively(Duration.ofSeconds(2),
30+
() -> new Server(crafted));
31+
assertEquals(crafted, server.getFullyQualifiedName());
32+
}
33+
1734
@Test
1835
public void testServerNameParsing() throws Exception {
1936
final String serverName = "LOCALHOST";

0 commit comments

Comments
 (0)