@@ -10,6 +10,7 @@ internal sealed class ToUnicodeCMap {
1010 private readonly Dictionary < string , string > _reverseMap = new ( StringComparer . Ordinal ) ;
1111 private int _maxKeyBytes = 1 ;
1212 private int _maxReverseTextLength = 1 ;
13+ private int _processedMappings ;
1314
1415 public static bool TryParse ( byte [ ] data , out ToUnicodeCMap ? cmap ) {
1516 try {
@@ -25,20 +26,36 @@ private void Parse(string s) {
2526 var bfchar = new Regex ( @"<(?<src>[0-9A-Fa-f]+)>\s+<(?<dst>[0-9A-Fa-f]+)>" ) ;
2627 foreach ( Match section in Regex . Matches ( s , @"beginbfchar([\s\S]*?)endbfchar" , RegexOptions . IgnoreCase ) ) {
2728 foreach ( Match m in bfchar . Matches ( section . Groups [ 1 ] . Value ) ) {
29+ if ( HasReachedMappingLimit ( ) ) {
30+ break ;
31+ }
32+
2833 AddMap ( m . Groups [ "src" ] . Value , m . Groups [ "dst" ] . Value ) ;
2934 }
35+
36+ if ( HasReachedMappingLimit ( ) ) {
37+ break ;
38+ }
3039 }
3140 // Handle beginbfrange / endbfrange, sequential mapping
3241 var bfrangeLine = new Regex ( @"<(?<from>[0-9A-Fa-f]+)>\s+<(?<to>[0-9A-Fa-f]+)>\s+<(?<dst>[0-9A-Fa-f]+)>" ) ;
3342 foreach ( Match section in Regex . Matches ( s , @"beginbfrange([\s\S]*?)endbfrange" , RegexOptions . IgnoreCase ) ) {
43+ if ( HasReachedMappingLimit ( ) ) {
44+ break ;
45+ }
46+
3447 string body = section . Groups [ 1 ] . Value ;
3548 string sequentialBody = Regex . Replace ( body , @"<(?<from>[0-9A-Fa-f]+)>\s+<(?<to>[0-9A-Fa-f]+)>\s+\[(?<dsts>[\s\S]*?)\]" , string . Empty , RegexOptions . IgnoreCase ) ;
3649 foreach ( Match m in bfrangeLine . Matches ( sequentialBody ) ) {
50+ if ( HasReachedMappingLimit ( ) ) {
51+ break ;
52+ }
53+
3754 int from = Convert . ToInt32 ( m . Groups [ "from" ] . Value , 16 ) ;
3855 int to = Convert . ToInt32 ( m . Groups [ "to" ] . Value , 16 ) ;
3956 int dst = Convert . ToInt32 ( m . Groups [ "dst" ] . Value , 16 ) ;
4057 int rangeLength = to >= from ? to - from + 1 : 0 ;
41- if ( rangeLength <= 0 || rangeLength > MaxRangeMappings || _map . Count + rangeLength > MaxMappings ) {
58+ if ( rangeLength <= 0 || rangeLength > MaxRangeMappings || _processedMappings + rangeLength > MaxMappings ) {
4259 continue ;
4360 }
4461
@@ -51,6 +68,10 @@ private void Parse(string s) {
5168 }
5269
5370 foreach ( Match m in Regex . Matches ( body , @"<(?<from>[0-9A-Fa-f]+)>\s+<(?<to>[0-9A-Fa-f]+)>\s+\[(?<dsts>[\s\S]*?)\]" , RegexOptions . IgnoreCase ) ) {
71+ if ( HasReachedMappingLimit ( ) ) {
72+ break ;
73+ }
74+
5475 int from = Convert . ToInt32 ( m . Groups [ "from" ] . Value , 16 ) ;
5576 int to = Convert . ToInt32 ( m . Groups [ "to" ] . Value , 16 ) ;
5677 int keyBytes = m . Groups [ "from" ] . Value . Length / 2 ;
@@ -60,7 +81,7 @@ private void Parse(string s) {
6081 break ;
6182 }
6283
63- if ( _map . Count >= MaxMappings || code - from >= MaxRangeMappings ) {
84+ if ( HasReachedMappingLimit ( ) || code - from >= MaxRangeMappings ) {
6485 break ;
6586 }
6687
@@ -73,10 +94,11 @@ private void Parse(string s) {
7394 }
7495
7596 private void AddMap ( string srcHex , string dstHex ) {
76- if ( _map . Count >= MaxMappings ) {
97+ if ( HasReachedMappingLimit ( ) ) {
7798 return ;
7899 }
79100
101+ _processedMappings ++ ;
80102 srcHex = RemoveHexWhitespace ( srcHex ) ;
81103 dstHex = RemoveHexWhitespace ( dstHex ) ;
82104 if ( srcHex . Length % 2 != 0 ) srcHex = "0" + srcHex ;
@@ -94,6 +116,8 @@ private void AddMap(string srcHex, string dstHex) {
94116 }
95117 }
96118
119+ private bool HasReachedMappingLimit ( ) => _processedMappings >= MaxMappings ;
120+
97121 private static string RemoveHexWhitespace ( string value ) {
98122 bool hasWhitespace = false ;
99123 for ( int i = 0 ; i < value . Length ; i ++ ) {
0 commit comments