-
Notifications
You must be signed in to change notification settings - Fork 215
Description
Description
In PHP 8.x, a deprecation warning is triggered in Zend_Db_Statement::_parseParameters() at line 140:
preg_split(): Passing null to parameter #2 ($subject) of type string is deprecated
Root Cause
The issue originates in Zend_Db_Statement::_stripQuoted(). When processing large SQL queries (especially those with many values in an IN (?) clause), the preg_replace() calls at lines 194, 200, and 212 can fail due to PCRE backtrack limit being exceeded.
When preg_replace() fails, it returns null instead of a string. This null value is then passed to preg_split() in _parseParameters(), triggering the deprecation warning.
Code References
_stripQuoted() - lines 194, 200, 212:
$sql = preg_replace("/$q([^$q{$escapeChar}]*|($qe)*)*$q/s", '', (string) $sql);
// ...
$sql = preg_replace("/\"(\\\\\"|[^\"])*\"/Us", '', (string) $sql);
// ...
$sql = preg_replace("/$d($de|\\\\{2}|[^$d])*$d/Us", '', (string) $sql);
_parseParameters() - line 140:
$this->_sqlSplit = preg_split('/(\?|\:[a-zA-Z0-9_]+)/',
$sql, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);Suggested Fix
Check for null return values from preg_replace() and keep the original SQL string in that case:
protected function _stripQuoted($sql)
{
$sql = (string) $sql;
$q = $this->_adapter->quote('a');
$q = $q[0];
$qe = $this->_adapter->quote($q);
$qe = substr($qe, 1, 2);
$qe = preg_quote($qe);
$escapeChar = substr($qe, 0, 1);
if (!empty($q)) {
$escapeChar = preg_quote($escapeChar);
$result = preg_replace("/$q([^$q{$escapeChar}]*|($qe)*)*$q/s", '', $sql);
if ($result !== null) {
$sql = $result;
}
}
$result = preg_replace("/\"(\\\\\"|[^\"])*\"/Us", '', $sql);
if ($result !== null) {
$sql = $result;
}
$d = $this->_adapter->quoteIdentifier('a');
$d = $d[0];
$de = $this->_adapter->quoteIdentifier($d);
$de = substr($de, 1, 2);
$de = preg_quote($de);
$result = preg_replace("/$d($de|\\\\{2}|[^$d])*$d/Us", '', $sql);
if ($result !== null) {
$sql = $result;
}
return $sql;
}Environment
PHP version: 8.2.30
zf1-future version: latest
Current Workaround
Temporarily increasing pcre.backtrack_limit before executing queries:
$previousLimit = ini_get('pcre.backtrack_limit');
ini_set('pcre.backtrack_limit', 10000000);
// execute query
ini_set('pcre.backtrack_limit', $previousLimit);