I just noticed I omitted one essential line in the reproduction
code:
$db = Zend_Db_Table::getDefaultAdapter();
$value = str_repeat('a', 66000) . 'x';
$query = "INSERT INTO `pcre` (`test`) VALUES ('$value')";
$this->view->query = $query;
var_dump($db->query($query)); // added this line, that
actually triggers the segfault, if it exists
Op 21-05-12 16:42, Bart McLeod schreef:
OK,
Let me follow up with the details in case you are interested to
contribute by testing the fix on your system against your
database. This is important, we need all the help we can get!
I can reproduce issue ZF-5063 with the following code:
$db = Zend_Db_Table::getDefaultAdapter();
$value = str_repeat('a', 66000) . 'x'; // 66,000 times an
'a' with an 'x' appended to it, to identify the end.
$query = "INSERT INTO `pcre` (`test`) VALUES ('$value')";
In my case, the default adapter was mysql and I am on a 64bit
system.
You might get a segmentation fault from this, which you can see in
you apache error log. The code snippet was inside a controller
action of a default Zend Framework project (see the full code
below).
To reproduce with this code, you need a database connection and a
table named 'pcre' with a field named 'test' (of type LONG_TEXT in
mysql). In my case, this was the only field.
**Fix the segfault in case you get it**
In case you also reproduce the segfault, you can add a setting to
php.ini to modify the behavior of the PCRE library, that is
causing the segfault:
[PCRE]
pcre.recursion_limit = 1000
If you set this, the segfault should dissapear. The default
pcre.recursion_limit = 100000, which is too high, apparently.
If you set it to a value that is simply to low, you will get many
errors accross many components.
If you have or get idea's on what an optimum default setting would
be, please let us know.
Instead of the segfault, you will either get a memory_limit error,
which is ok, since you can increase the memory_limit if you need
to, or you will get a database error because you query exceeds the
maximum size, in case that is too low. You can play with how much
you allow as the maximum packet size for your database and the
memory_limit in php, but in the end, it is important that **you do
no longer get the segmentation fault**. If you don't and you did
before, you have found a working setting for pcre.recursion_limit.
The query above is a very simple query. We would like to know if
real life queries that previously caused a segfault, will work
now, with the new implementation and optionally a different
recursion_limit on PCRE.
I intend to change the current implementation of Zend_Db_Statement
so that it sets a sensible default for pcre.recursion_limit at
runtime and restores the original limit afterwards. In addition, I
would like to make this configurable through the adapter
configuration, so that you can change the default if it not right
for a specific use case you may have.
**Full controller code:**
/**
* DbController
*/
class DbController extends Zend_Controller_Action
{
// http://localhost/db/st
public function stAction()
{
$db = Zend_Db_Table::getDefaultAdapter();
$value = str_repeat('a', 66000) . 'x';
$query = "INSERT INTO `pcre` (`test`) VALUES ('$value')";
$this->view->query = $query;
}
}
Op 21-05-12 15:59, Ralph Schindler schreef:
Hi all,
In the past we've been reluctant to solve an issue inside
Zend_Db_Statement::_stripQuoted() that caused PHP's PCRE to
seg-fault and crash.
http://framework.zend.com/issues/browse/ZF-5063
http://framework.zend.com/issues/browse/ZF-10209
We've been reluctant for a number of reasons:
* the problem is not directly in ZF, but in PHP's PCRE
* the problem is only exposed on certain architectures
* fixing the problem might cause unintended BC issues
That said, given the amount of research a number of contributors
have put into the matter, primarily by Bart McLeod, we feel
comfortable moving forward with this fix for ZF 1.12 as it gives
developers some flexibility in avoiding the problem, and the fix
is fairly well tested against BC issues.
I will let Bart get into the complexities of the fix, but I
would like everyone to test what is currently in _trunk_ if you
have large SQL that is being passed through Zend_Db.
Thanks!
Ralph Schindler
|