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

Creating a RepeatCharacterRegexRule generates an exception in certain Locale's #134

Closed
ptmarquis opened this issue Sep 20, 2022 · 2 comments · Fixed by #135
Closed

Creating a RepeatCharacterRegexRule generates an exception in certain Locale's #134

ptmarquis opened this issue Sep 20, 2022 · 2 comments · Fixed by #135
Assignees

Comments

@ptmarquis
Copy link

Creating an instance of RepeatCharacterRegexRule will generate an exception in certain Locale's. The regular expression used internally by the class will include a repetition count that is non-ASCII. Below is a TestNG test case demonstrating the issue

package org.passay;

import java.util.Locale;
import org.testng.annotations.Test;

public class ArabicTest {
    @Test
    public void test() {
        // Get the current default Locale
        final Locale defaultLocale = Locale.getDefault();
        try {
            // Set the default Locale to ar-US
            final Locale arUS = new Locale.Builder()
                    .setLanguage("ar")
                    .setRegion("US")
                    .build();
            Locale.setDefault(arUS);

            // In this Locale, the generated regular expressions includes
            // a repetition count that is non-ASCII
            final RepeatCharacterRegexRule rule = new RepeatCharacterRegexRule();
        } finally {
            Locale.setDefault(defaultLocale);
        }
    }
}

Stack trace

java.util.regex.PatternSyntaxException: Illegal repetition near index 17
([^\x00-\x1F])\1{٤}
                 ^

	at java.base/java.util.regex.Pattern.error(Pattern.java:2028)
	at java.base/java.util.regex.Pattern.closure(Pattern.java:3309)
	at java.base/java.util.regex.Pattern.sequence(Pattern.java:2214)
	at java.base/java.util.regex.Pattern.expr(Pattern.java:2069)
	at java.base/java.util.regex.Pattern.compile(Pattern.java:1783)
	at java.base/java.util.regex.Pattern.<init>(Pattern.java:1430)
	at java.base/java.util.regex.Pattern.compile(Pattern.java:1069)
	at org.passay.IllegalRegexRule.<init>(IllegalRegexRule.java:61)
	at org.passay.RepeatCharacterRegexRule.<init>(RepeatCharacterRegexRule.java:56)
	at org.passay.RepeatCharacterRegexRule.<init>(RepeatCharacterRegexRule.java:44)
	at org.passay.RepeatCharacterRegexRule.<init>(RepeatCharacterRegexRule.java:33)
	at org.passay.ArabicTest.test(ArabicTest.java:20)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:135)
	at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:673)
	at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:220)
	at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50)
	at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:945)
	at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:193)
	at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
	at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.testng.TestRunner.privateRun(TestRunner.java:808)
	at org.testng.TestRunner.run(TestRunner.java:603)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:429)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:423)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:383)
	at org.testng.SuiteRunner.run(SuiteRunner.java:326)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1249)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
	at org.testng.TestNG.runSuites(TestNG.java:1092)
	at org.testng.TestNG.run(TestNG.java:1060)
	at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
	at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
@ptmarquis
Copy link
Author

One way to fix this is to specify a Locale in the call to String#format when creating the regular expression. Diff below

diff --git a/src/main/java/org/passay/RepeatCharacterRegexRule.java b/src/main/java/org/passay/RepeatCharacterRegexRule.java
index c0b89e4..4250d39 100644
--- a/src/main/java/org/passay/RepeatCharacterRegexRule.java
+++ b/src/main/java/org/passay/RepeatCharacterRegexRule.java
@@ -1,6 +1,8 @@
 /* See LICENSE for licensing and NOTICE for copyright. */
 package org.passay;
 
+import java.util.Locale;
+
 /**
  * Rule for determining if a password contains a duplicate ASCII keyboard sequence. See {@link java.util.regex.Pattern}
  * /p{ASCII}. The default sequence length is 5 characters.
@@ -53,7 +55,7 @@ public class RepeatCharacterRegexRule extends IllegalRegexRule
    */
   public RepeatCharacterRegexRule(final int sl, final boolean reportAll)
   {
-    super(String.format(REPEAT_CHAR_REGEX, sl - 1), reportAll);
+    super(String.format(Locale.ENGLISH, REPEAT_CHAR_REGEX, sl - 1), reportAll);
     if (sl < MINIMUM_SEQUENCE_LENGTH) {
       throw new IllegalArgumentException(String.format("sequence length must be >= %s", MINIMUM_SEQUENCE_LENGTH));
     }

@dfish3r dfish3r self-assigned this Sep 20, 2022
dfish3r added a commit that referenced this issue Sep 20, 2022
RepeatCharacterRegexRule uses String#format to create a regular expression.
That operation is problematic in non-english locales.
Define a specific locale for the operation.
Fixes #134.
@ptmarquis
Copy link
Author

Thanks for fixing this so quickly!

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

Successfully merging a pull request may close this issue.

2 participants