@@ -275,7 +275,8 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
275
275
get to the end without encountering a delimiter. */
276
276
while (isspace ((int )* (unsigned char * )p )) p ++ ;
277
277
if (* p == 0 ) {
278
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "Empty regular expression ");
278
+ php_error_docref (NULL TSRMLS_CC , E_WARNING ,
279
+ p < regex + regex_len ? "Null byte in regex" : "Empty regular expression" );
279
280
return NULL ;
280
281
}
281
282
@@ -292,29 +293,25 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
292
293
delimiter = pp [5 ];
293
294
end_delimiter = delimiter ;
294
295
296
+ pp = p ;
297
+
295
298
if (start_delimiter == end_delimiter ) {
296
299
/* We need to iterate through the pattern, searching for the ending delimiter,
297
300
but skipping the backslashed delimiters. If the ending delimiter is not
298
301
found, display a warning. */
299
- pp = p ;
300
302
while (* pp != 0 ) {
301
303
if (* pp == '\\' && pp [1 ] != 0 ) pp ++ ;
302
304
else if (* pp == delimiter )
303
305
break ;
304
306
pp ++ ;
305
307
}
306
- if (* pp == 0 ) {
307
- php_error_docref (NULL TSRMLS_CC ,E_WARNING , "No ending delimiter '%c' found" , delimiter );
308
- return NULL ;
309
- }
310
308
} else {
311
309
/* We iterate through the pattern, searching for the matching ending
312
310
* delimiter. For each matching starting delimiter, we increment nesting
313
311
* level, and decrement it for each matching ending delimiter. If we
314
312
* reach the end of the pattern without matching, display a warning.
315
313
*/
316
314
int brackets = 1 ; /* brackets nesting level */
317
- pp = p ;
318
315
while (* pp != 0 ) {
319
316
if (* pp == '\\' && pp [1 ] != 0 ) pp ++ ;
320
317
else if (* pp == end_delimiter && -- brackets <= 0 )
@@ -323,10 +320,17 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
323
320
brackets ++ ;
324
321
pp ++ ;
325
322
}
326
- if (* pp == 0 ) {
327
- php_error_docref (NULL TSRMLS_CC ,E_WARNING , "No ending matching delimiter '%c' found" , end_delimiter );
328
- return NULL ;
323
+ }
324
+
325
+ if (* pp == 0 ) {
326
+ if (pp < regex + regex_len ) {
327
+ php_error_docref (NULL TSRMLS_CC ,E_WARNING , "Null byte in regex" );
328
+ } else if (start_delimiter == end_delimiter ) {
329
+ php_error_docref (NULL TSRMLS_CC ,E_WARNING , "No ending delimiter '%c' found" , delimiter );
330
+ } else {
331
+ php_error_docref (NULL TSRMLS_CC ,E_WARNING , "No ending matching delimiter '%c' found" , delimiter );
329
332
}
333
+ return NULL ;
330
334
}
331
335
332
336
/* Make a copy of the actual pattern. */
@@ -337,7 +341,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
337
341
338
342
/* Parse through the options, setting appropriate flags. Display
339
343
a warning if we encounter an unknown modifier. */
340
- while (* pp != 0 ) {
344
+ while (pp < regex + regex_len ) {
341
345
switch (* pp ++ ) {
342
346
/* Perl compatible options */
343
347
case 'i' : coptions |= PCRE_CASELESS ; break ;
@@ -368,7 +372,11 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
368
372
break ;
369
373
370
374
default :
371
- php_error_docref (NULL TSRMLS_CC ,E_WARNING , "Unknown modifier '%c'" , pp [-1 ]);
375
+ if (pp [-1 ]) {
376
+ php_error_docref (NULL TSRMLS_CC ,E_WARNING , "Unknown modifier '%c'" , pp [-1 ]);
377
+ } else {
378
+ php_error_docref (NULL TSRMLS_CC ,E_WARNING , "Null byte in regex" );
379
+ }
372
380
efree (pattern );
373
381
return NULL ;
374
382
}
0 commit comments