@@ -149,40 +149,43 @@ private function getCommonPrefix(string $prefix, string $anotherPrefix): array
149
149
$ staticLength = null ;
150
150
set_error_handler ([__CLASS__ , 'handleError ' ]);
151
151
152
- for ($ i = $ baseLength ; $ i < $ end && $ prefix [$ i ] === $ anotherPrefix [$ i ]; ++$ i ) {
153
- if ('( ' === $ prefix [$ i ]) {
154
- $ staticLength = $ staticLength ?? $ i ;
155
- for ($ j = 1 + $ i , $ n = 1 ; $ j < $ end && 0 < $ n ; ++$ j ) {
156
- if ($ prefix [$ j ] !== $ anotherPrefix [$ j ]) {
157
- break 2 ;
152
+ try {
153
+ for ($ i = $ baseLength ; $ i < $ end && $ prefix [$ i ] === $ anotherPrefix [$ i ]; ++$ i ) {
154
+ if ('( ' === $ prefix [$ i ]) {
155
+ $ staticLength = $ staticLength ?? $ i ;
156
+ for ($ j = 1 + $ i , $ n = 1 ; $ j < $ end && 0 < $ n ; ++$ j ) {
157
+ if ($ prefix [$ j ] !== $ anotherPrefix [$ j ]) {
158
+ break 2 ;
159
+ }
160
+ if ('( ' === $ prefix [$ j ]) {
161
+ ++$ n ;
162
+ } elseif (') ' === $ prefix [$ j ]) {
163
+ --$ n ;
164
+ } elseif ('\\' === $ prefix [$ j ] && (++$ j === $ end || $ prefix [$ j ] !== $ anotherPrefix [$ j ])) {
165
+ --$ j ;
166
+ break ;
167
+ }
158
168
}
159
- if ('( ' === $ prefix [$ j ]) {
160
- ++$ n ;
161
- } elseif (') ' === $ prefix [$ j ]) {
162
- --$ n ;
163
- } elseif ('\\' === $ prefix [$ j ] && (++$ j === $ end || $ prefix [$ j ] !== $ anotherPrefix [$ j ])) {
164
- --$ j ;
169
+ if (0 < $ n ) {
165
170
break ;
166
171
}
167
- }
168
- if (0 < $ n ) {
169
- break ;
170
- }
171
- if (('? ' === ($ prefix [$ j ] ?? '' ) || '? ' === ($ anotherPrefix [$ j ] ?? '' )) && ($ prefix [$ j ] ?? '' ) !== ($ anotherPrefix [$ j ] ?? '' )) {
172
- break ;
173
- }
174
- $ subPattern = substr ($ prefix , $ i , $ j - $ i );
175
- if ($ prefix !== $ anotherPrefix && !preg_match ('/^\(\[[^\]]++\]\+\+\)$/ ' , $ subPattern ) && !preg_match ('{(?<! ' .$ subPattern .')} ' , '' )) {
176
- // sub-patterns of variable length are not considered as common prefixes because their greediness would break in-order matching
172
+ if (('? ' === ($ prefix [$ j ] ?? '' ) || '? ' === ($ anotherPrefix [$ j ] ?? '' )) && ($ prefix [$ j ] ?? '' ) !== ($ anotherPrefix [$ j ] ?? '' )) {
173
+ break ;
174
+ }
175
+ $ subPattern = substr ($ prefix , $ i , $ j - $ i );
176
+ if ($ prefix !== $ anotherPrefix && !preg_match ('/^\(\[[^\]]++\]\+\+\)$/ ' , $ subPattern ) && !preg_match ('{(?<! ' .$ subPattern .')} ' , '' )) {
177
+ // sub-patterns of variable length are not considered as common prefixes because their greediness would break in-order matching
178
+ break ;
179
+ }
180
+ $ i = $ j - 1 ;
181
+ } elseif ('\\' === $ prefix [$ i ] && (++$ i === $ end || $ prefix [$ i ] !== $ anotherPrefix [$ i ])) {
182
+ --$ i ;
177
183
break ;
178
184
}
179
- $ i = $ j - 1 ;
180
- } elseif ('\\' === $ prefix [$ i ] && (++$ i === $ end || $ prefix [$ i ] !== $ anotherPrefix [$ i ])) {
181
- --$ i ;
182
- break ;
183
185
}
186
+ } finally {
187
+ restore_error_handler ();
184
188
}
185
- restore_error_handler ();
186
189
if ($ i < $ end && 0b10 === (\ord ($ prefix [$ i ]) >> 6 ) && preg_match ('//u ' , $ prefix .' ' .$ anotherPrefix )) {
187
190
do {
188
191
// Prevent cutting in the middle of an UTF-8 characters
0 commit comments