Bugs of preg_match (PHP-version 5.2.5)
In most cases, the following example will show one of two PHP-bugs discovered with preg_match depending on your PHP-version and configuration.
<?php
$text = "test=";
for ($i = 0; $i++ < 100000;)
$text .= "%AB";
$pattern = '/^(?:[;\/?:@&=+$,]|(?:[^\W_]|[-_.!~*\()\[\] ])|(?:%[\da-fA-F]{2}))*$/';
var_dump( preg_match( $pattern, $text ) );
?>
Possible bug (1):
=============
On one of our Linux-Servers the above example crashes PHP-execution with a C(?) Segmentation Fault(!). This seems to be a known bug (see http://bugs.php.net/bug.php?id=40909), but I don't know if it has been fixed, yet.
If you are looking for a work-around, the following code-snippet is what I found helpful. It wraps the possibly crashing preg_match call by decreasing the PCRE recursion limit in order to result in a Reg-Exp error instead of a PHP-crash.
<?php
[...]
$former_recursion_limit = ini_set( "pcre.recursion_limit", 10000 );
$result = preg_match( $pattern, $text );
ini_set( "pcre.recursion_limit", $former_recursion_limit );
if ( PREG_RECURSION_LIMIT_ERROR === preg_last_error() )
{
$result = [...];
[...]
} ?>
Possible bug (2):
=============
On one of our Windows-Servers the above example does not crash PHP, but (directly) hits the recursion-limit. Here, the problem is that preg_match does not return boolean(false) as expected by the description / manual of above.
In short, preg_match seems to return an int(0) instead of the expected boolean(false) if the regular expression could not be executed due to the PCRE recursion-limit. So, if preg_match results in int(0) you seem to have to check preg_last_error() if maybe an error occurred.