@@ -271,6 +271,7 @@ uint64_t random_options;
271
271
pcre2_match_data * match_data = NULL ;
272
272
#ifdef SUPPORT_JIT
273
273
pcre2_match_data * match_data_jit = NULL ;
274
+ PCRE2_UCHAR * newwdata = NULL ;
274
275
#endif
275
276
pcre2_match_context * match_context = NULL ;
276
277
size_t match_size ;
@@ -291,75 +292,83 @@ get around this, we scan the data string for large quantifiers that follow a
291
292
closing parenthesis, and reduce the value of the quantifier to 10, assuming
292
293
that this will make minimal difference to the detection of bugs.
293
294
294
- Start the scan at the second character so there can be a lookbehind for a
295
- backslash, and end it before the end so that the next character can be checked
296
- for an opening brace. */
295
+ We have to make a copy of the input because oss-fuzz complains if we overwrite
296
+ the original. Start the scan at the second character so there can be a
297
+ lookbehind for a backslash, and end it before the end so that the next
298
+ character can be checked for an opening brace. */
297
299
298
- if (size > 3 ) for ( size_t i = 1 ; i < size - 2 ; i ++ )
300
+ if (size > 3 )
299
301
{
300
- size_t j ;
301
-
302
- if (wdata [i ] != ')' || wdata [i - 1 ] == '\\' || wdata [i + 1 ] != '{' ) continue ;
303
- i ++ ; /* Points to '{' */
302
+ newwdata = malloc (size * sizeof (PCRE2_UCHAR ));
303
+ memcpy (newwdata , wdata , size * sizeof (PCRE2_UCHAR ));
304
+ wdata = newwdata ;
304
305
305
- /* Loop for two values a quantifier. Offset i points to brace or comma at the
306
- start of the loop.*/
307
-
308
- for (int ii = 0 ; ii < 2 ; ii ++ )
306
+ for (size_t i = 1 ; i < size - 2 ; i ++ )
309
307
{
310
- int q = 0 ;
308
+ size_t j ;
309
+
310
+ if (wdata [i ] != ')' || wdata [i - 1 ] == '\\' || wdata [i + 1 ] != '{' ) continue ;
311
+ i ++ ; /* Points to '{' */
311
312
312
- /* Ignore leading spaces */
313
+ /* Loop for two values a quantifier. Offset i points to brace or comma at the
314
+ start of the loop.*/
313
315
314
- while ( wdata [ i + 1 ] == ' ' || wdata [ i + 1 ] == '\t' )
316
+ for ( int ii = 0 ; ii < 2 ; ii ++ )
315
317
{
316
- i ++ ;
317
- if (i >= size - 1 ) goto END_QSCAN ;
318
- }
318
+ int q = 0 ;
319
319
320
- /* Scan for a number ending in brace or comma in the first iteration,
321
- optionally preceded by space. */
320
+ /* Ignore leading spaces */
322
321
323
- for (j = i + 1 ; j < size && j < i + 7 ; j ++ )
324
- {
325
- if (wdata [j ] == ' ' || wdata [j ] == '\t' )
322
+ while (wdata [i + 1 ] == ' ' || wdata [i + 1 ] == '\t' )
326
323
{
327
- do j ++ ; while ( j < size && ( wdata [ j ] == ' ' || wdata [ j ] == '\t' )) ;
328
- if (wdata [ j ] != '}' && wdata [ j ] != ',' ) goto OUTERLOOP ;
324
+ i ++ ;
325
+ if (i >= size - 1 ) goto END_QSCAN ;
329
326
}
330
- if (wdata [j ] == '}' || (ii == 0 && wdata [j ] == ',' )) break ;
331
- if (wdata [j ] < '0' || wdata [j ] > '9' ) goto OUTERLOOP ;
332
- q = q * 10 + wdata [j ] - '0' ;
333
- }
334
327
335
- /* Hit ',' or '}' or read 6 digits. Six digits is a number > 65536 which is
336
- the maximum quantifier. Leave such numbers alone . */
328
+ /* Scan for a number ending in brace or comma in the first iteration,
329
+ optionally preceded by space . */
337
330
338
- if (j >= i + 7 || q > 65535 ) goto OUTERLOOP ;
331
+ for (j = i + 1 ; j < size && j < i + 7 ; j ++ )
332
+ {
333
+ if (wdata [j ] == ' ' || wdata [j ] == '\t' )
334
+ {
335
+ do j ++ ; while (j < size && (wdata [j ] == ' ' || wdata [j ] == '\t' ));
336
+ if (wdata [j ] != '}' && wdata [j ] != ',' ) goto OUTERLOOP ;
337
+ }
338
+ if (wdata [j ] == '}' || (ii == 0 && wdata [j ] == ',' )) break ;
339
+ if (wdata [j ] < '0' || wdata [j ] > '9' ) goto OUTERLOOP ;
340
+ q = q * 10 + wdata [j ] - '0' ;
341
+ }
339
342
340
- /* Limit the quantifier size to 10 */
343
+ /* Hit ',' or '}' or read 6 digits. Six digits is a number > 65536 which is
344
+ the maximum quantifier. Leave such numbers alone. */
341
345
342
- if (q > 10 )
343
- {
346
+ if (j >= i + 7 || q > 65535 ) goto OUTERLOOP ;
347
+
348
+ /* Limit the quantifier size to 10 */
349
+
350
+ if (q > 10 )
351
+ {
344
352
#ifdef STANDALONE
345
- printf ("Reduced quantifier value %d to 10.\n" , q );
353
+ printf ("Reduced quantifier value %d to 10.\n" , q );
346
354
#endif
347
- for (size_t k = i + 1 ; k < j ; k ++ ) wdata [k ] = '0' ;
348
- wdata [j - 2 ] = '1' ;
355
+ for (size_t k = i + 1 ; k < j ; k ++ ) wdata [k ] = '0' ;
356
+ wdata [j - 2 ] = '1' ;
357
+ }
358
+
359
+ /* Advance to end of number and break if reached closing brace (continue
360
+ after comma, which is only valid in the first time round this loop). */
361
+
362
+ i = j ;
363
+ if (wdata [i ] == '}' ) break ;
349
364
}
350
365
351
- /* Advance to end of number and break if reached closing brace (continue
352
- after comma, which is only valid in the first time round this loop). */
366
+ /* Continue along the data string */
353
367
368
+ OUTERLOOP :
354
369
i = j ;
355
- if ( wdata [ i ] == '}' ) break ;
370
+ continue ;
356
371
}
357
-
358
- /* Continue along the data string */
359
-
360
- OUTERLOOP :
361
- i = j ;
362
- continue ;
363
372
}
364
373
END_QSCAN :
365
374
#endif /* SUPPORT_JIT */
@@ -635,6 +644,7 @@ with the interpreter. */
635
644
if (match_data != NULL ) pcre2_match_data_free (match_data );
636
645
#ifdef SUPPORT_JIT
637
646
if (match_data_jit != NULL ) pcre2_match_data_free (match_data_jit );
647
+ free (newwdata );
638
648
#endif
639
649
if (match_context != NULL ) pcre2_match_context_free (match_context );
640
650
0 commit comments