--- /dev/null
+--TEST--
+Backtracking limit
+--INI--
+pcre.backtrack_limit=2
+--FILE--
+<?php
+
+var_dump(preg_match_all('/.*\p{N}/', '0123456789', $dummy));
+var_dump(preg_last_error() === PREG_BACKTRACK_LIMIT_ERROR);
+
+var_dump(preg_match_all('/\p{Nd}/', '0123456789', $dummy));
+var_dump(preg_last_error() === PREG_NO_ERROR);
+
+?>
+--EXPECT--
+int(0)
+bool(true)
+int(10)
+bool(true)
--- /dev/null
+--TEST--
+Compiled regex cache limit
+--FILE--
+<?php
+define('PREG_CACHE_SIZE', 4096+1);
+
+$re = '';
+$str = str_repeat('x', PREG_CACHE_SIZE);
+
+for ($i=0; $i < PREG_CACHE_SIZE; ++$i) {
+ $re .= '.';
+ if (!preg_match("/$re/", $str)) {
+ die('non match. error');
+ }
+}
+
+var_dump(preg_match('/./', $str)); // this one was already deleted from the cache
+var_dump(preg_match("/$re/", $str)); // but not this one
+
+echo "done\n";
+?>
+--EXPECT--
+int(1)
+int(1)
+done
--- /dev/null
+--TEST--
+Delimiters crash test
+--FILE--
+<?php
+
+var_dump(preg_match('', ''));
+var_dump(preg_match(' ', ''));
+var_dump(preg_match('@@', ''));
+var_dump(preg_match('12', ''));
+var_dump(preg_match('<>', ''));
+var_dump(preg_match('~a', ''));
+var_dump(preg_match('@\@\@@', '@@'));
+var_dump(preg_match('//z', '@@'));
+
+?>
+--EXPECTF--
+Warning: preg_match(): Empty regular expression in %sdelimiters.php on line 3
+bool(false)
+
+Warning: preg_match(): Empty regular expression in %sdelimiters.php on line 4
+bool(false)
+int(1)
+
+Warning: preg_match(): Delimiter must not be alphanumeric or backslash in %sdelimiters.php on line 6
+bool(false)
+int(1)
+
+Warning: preg_match(): No ending delimiter '~' found in %sdelimiters.php on line 8
+bool(false)
+int(1)
+
+Warning: preg_match(): Unknown modifier 'z' in %sdelimiters.php on line 10
+bool(false)
--- /dev/null
+--TEST--
+preg_grep()
+--FILE--
+<?php
+$array = array('a', '1', 'q6', 'h20');
+
+var_dump(preg_grep('/^(\d|.\d)$/', $array));
+var_dump(preg_grep('/^(\d|.\d)$/', $array, PREG_GREP_INVERT));
+
+?>
+--EXPECT--
+array(2) {
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(2) "q6"
+}
+array(2) {
+ [0]=>
+ string(1) "a"
+ [3]=>
+ string(3) "h20"
+}
--- /dev/null
+--TEST--
+Localized match
+--SKIPIF--
+<?php if (!function_exists('setlocale')) die('setlocale() not available'); ?>
+--FILE--
+<?php
+
+// this tests if the cache is working correctly, as the char tables
+// must be rebuilt after the locale change
+
+setlocale(LC_ALL, 'C', 'POSIX');
+var_dump(preg_match('/^\w{6}$/', 'aàáçéè'));
+
+setlocale(LC_ALL, 'pt_PT', 'pt', 'portuguese');
+var_dump(preg_match('/^\w{6}$/', 'aàáçéè'));
+
+setlocale(LC_ALL, 'C', 'POSIX');
+var_dump(preg_match('/^\w{6}$/', 'aàáçéè'));
+
+?>
+--EXPECT--
+int(0)
+int(1)
+int(0)
--- /dev/null
+--TEST--
+Multi-line match
+--FILE--
+<?php
+
+var_dump(preg_match_all('/^.{2,3}$/', "aei\nou", $dummy));
+var_dump(preg_match_all('/^.{2,3}$/', "aei\nou\n", $dummy));
+var_dump(preg_match_all('/^.{2,3}$/m', "aei\nou", $dummy));
+var_dump(preg_match_all('/^.{2,3}$/m', "aei\nou\n", $dummy));
+
+echo "done\n";
+?>
+--EXPECT--
+int(0)
+int(0)
+int(2)
+int(2)
+done
--- /dev/null
+--TEST--
+PCRE Recursion limit
+--INI--
+pcre.recursion_limit=2
+--FILE--
+<?php
+
+var_dump(preg_match_all('/\p{Ll}(\p{L}((\p{Ll}\p{Ll})))/', 'aeiou', $dummy));
+var_dump(preg_last_error() === PREG_RECURSION_LIMIT_ERROR);
+
+var_dump(preg_match_all('/\p{Ll}\p{L}\p{Ll}\p{Ll}/', 'aeiou', $dummy));
+var_dump(preg_last_error() === PREG_NO_ERROR);
+
+?>
+--EXPECT--
+int(0)
+bool(true)
+int(1)
+bool(true)
--- /dev/null
+--TEST--
+Study regex
+--FILE--
+<?php
+
+var_dump(preg_match('/(?:(?:(?:(?:(?:(.))))))/ S', 'aeiou', $dump));
+var_dump($dump[1]);
+var_dump(preg_match('/(?:(?:(?:(?:(?:(.))))))/', 'aeiou', $dump));
+var_dump($dump[1]);
+
+var_dump(preg_match('/(?>..)((?:(?>.)|.|.|.|u))/S', 'aeiou', $dump));
+var_dump($dump[1]);
+
+// try to trigger usual "match known text" optimization
+var_dump(preg_match('/^aeiou$/S', 'aeiou', $dump));
+var_dump($dump[0]);
+var_dump(preg_match('/aeiou/S', 'aeiou', $dump));
+var_dump($dump[0]);
+
+?>
+--EXPECT--
+int(1)
+string(1) "a"
+int(1)
+string(1) "a"
+int(1)
+string(1) "i"
+int(1)
+string(5) "aeiou"
+int(1)
+string(5) "aeiou"