Skip to content

Commit

Permalink
Corrects Java's failure to match an end anchor when immediately prece…
Browse files Browse the repository at this point in the history
…ded by a quantifier.

Resolves #814
  • Loading branch information
Faron Dutton committed Jun 8, 2023
1 parent ac6ecd0 commit 0b68984
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
Expand Up @@ -9,9 +9,19 @@ class JDKRegularExpression implements RegularExpression {
private final boolean hasEndAnchor;

JDKRegularExpression(String regex) {
this.pattern = Pattern.compile(regex);
// The patterns in JSON Schema are not implicitly anchored so we must
// use Matcher.find(). However, this method does not honor the end
// anchor when immediately preceded by a quantifier (e.g., ?, *, +).
// To make this work in all cases, we wrap the pattern in a group.
this.hasStartAnchor = '^' == regex.charAt(0);
this.hasEndAnchor = '$' == regex.charAt(regex.length() - 1);
String pattern = regex;
if (this.hasEndAnchor) {
pattern = pattern.substring(this.hasStartAnchor ? 1 : 0, pattern.length() - 1);
pattern = '(' + pattern + ")$";
if (this.hasStartAnchor) pattern = '^' + pattern;
}
this.pattern = Pattern.compile(pattern);
}

@Override
Expand Down
47 changes: 47 additions & 0 deletions src/test/java/com/networknt/schema/regex/Issue814Test.java
@@ -0,0 +1,47 @@
package com.networknt.schema.regex;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class Issue814Test {

@Test
void jdkTypePattern() {
JDKRegularExpression ex = new JDKRegularExpression("^list|date|time|string|enum|int|double|long|boolean|number$");
assertTrue(ex.matches("list"));
assertTrue(ex.matches("string"));
assertTrue(ex.matches("boolean"));
assertTrue(ex.matches("number"));
assertTrue(ex.matches("enum"));
}

@Test
void jdkOptionsPattern() {
JDKRegularExpression ex = new JDKRegularExpression("^\\d*|[a-zA-Z_]+$");
assertTrue(ex.matches("external"));
assertTrue(ex.matches("external_gte"));
assertTrue(ex.matches("force"));
assertTrue(ex.matches("internal"));
}

@Test
void joniTypePattern() {
JoniRegularExpression ex = new JoniRegularExpression("^list|date|time|string|enum|int|double|long|boolean|number$");
assertTrue(ex.matches("list"));
assertTrue(ex.matches("string"));
assertTrue(ex.matches("boolean"));
assertTrue(ex.matches("number"));
assertTrue(ex.matches("enum"));
}

@Test
void joniOptionsPattern() {
JoniRegularExpression ex = new JoniRegularExpression("^\\d*|[a-zA-Z_]+$");
assertTrue(ex.matches("internal"));
assertTrue(ex.matches("external"));
assertTrue(ex.matches("external_gte"));
assertTrue(ex.matches("force"));
}

}

0 comments on commit 0b68984

Please sign in to comment.