ZF-10151: Improved notification in Http.php validateQuery() over preg_match crash caused by PHP backtracking bug
Description
Due to a known PHP-issue (see RegExp "Known Issues") a "simple" preg_match call may crash PHP-execution. So far, this only happened in the function validateQuery() of class Zend_Uri_Http (indirectly) used by the Zend_Http_Client when (over)long URL-queries were generated.
Workaround: reduce pcre.recursion_limit to a safe level for this call
--- library/Zend/Uri/Http.php (revision 22559)
+++ library/Zend/Uri/Http.php (working copy)
@@ -630,7 +630,34 @@
// Determine whether the query is well-formed
$pattern = '/^' . $this->_regex['uric'] . '*$/';
+
+ // ======================================================================
+ // added in order to fix Segmentation Fault problem that may appear
+ // on (over)long URLs with long URL-encoded parameters
+ // trying to catch a PHP-bug by decreasing backtracking- and recursion-limits ...
+ // ======================================================================
+
+ // decrease the PCRE recursion limit for the (possibly dangerous) preg_match call
+ $former_recursion_limit = ini_set("pcre.recursion_limit", 10000);
+
+ // the original call to pregmatch
$status = @preg_match($pattern, $query);
+
+ // reset the PCRE recursion limit to its original value
+ ini_set("pcre.recursion_limit", $former_recursion_limit);
+
+ // if the reg-exp has failed to our decreased recursion limit we (Zend) can not make
+ // any statement over the validity of the query and has to assume validity ;)
+ if (PREG_RECURSION_LIMIT_ERROR == preg_last_error()) {
+ $status = true;
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception("Zend_Uri_Http validateQuery check regular expression fails due to decreased PCRE recursion limit (preventing a possible C-Segmentation Fault). Query: $query" );
+ }
+
+ // ======================================================================
+ // END OF MODIFICATION
+ // ======================================================================
+
if ($status === false) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('Internal error: query validation failed');
Comments
Posted by François-Xavier MAURICARD (fxmauricard) on 2010-08-18T07:49:02.000+0000
In my install (PHP 5.3.3 on WinXP SP3), I had to limit the recursion to only 500. (limit is somewhere between 500 and 750).