@@ -725,7 +725,7 @@ public boolean matchStrings(String str, @Nullable Map<String, String> uriTemplat
725725 return this .caseSensitive ? this .rawPattern .equals (str ) : this .rawPattern .equalsIgnoreCase (str );
726726 }
727727 else if (this .pattern != null ) {
728- Matcher matcher = this .pattern .matcher (str );
728+ Matcher matcher = this .pattern .matcher (new MaxAttemptsCharSequence ( str ) );
729729 if (matcher .matches ()) {
730730 if (uriTemplateVariables != null ) {
731731 if (this .variableNames .size () != matcher .groupCount ()) {
@@ -750,6 +750,60 @@ else if (this.pattern != null) {
750750 return false ;
751751 }
752752
753+
754+ private static class MaxAttemptsCharSequence implements CharSequence {
755+
756+ private static final int MAX_ATTEMPTS = 1_000_000 ;
757+
758+ private final String text ;
759+
760+ private final Counter counter ;
761+
762+
763+ MaxAttemptsCharSequence (String text ) {
764+ this (text , new Counter ());
765+ }
766+
767+ private MaxAttemptsCharSequence (String text , Counter counter ) {
768+ this .text = text ;
769+ this .counter = counter ;
770+ }
771+
772+
773+ @ Override
774+ public int length () {
775+ return this .text .length ();
776+ }
777+
778+ @ Override
779+ public char charAt (int index ) {
780+ if (this .counter .value ++ >= MAX_ATTEMPTS ) {
781+ throw new IllegalStateException (
782+ "Too many character access attempts encountered during pattern matching" );
783+ }
784+ return this .text .charAt (index );
785+ }
786+
787+ @ Override
788+ public boolean isEmpty () {
789+ return this .text .isEmpty ();
790+ }
791+
792+ @ Override
793+ public CharSequence subSequence (int start , int end ) {
794+ return new MaxAttemptsCharSequence (this .text .substring (start , end ), this .counter );
795+ }
796+
797+ @ Override
798+ public String toString () {
799+ return this .text ;
800+ }
801+
802+
803+ private static class Counter {
804+ private int value ;
805+ }
806+ }
753807 }
754808
755809
0 commit comments