[php-src] Issue #8773: MySQL PDO: `PDOStatement::execute` returns `false` without neither throwing an exception nor setting `PDOStatement::errorCode`
if many (~1000) query parameters are bound

From: Date: Tue, 14 Jun 2022 07:19:57 +0000
Subject: [php-src] Issue #8773: MySQL PDO: `PDOStatement::execute` returns `false` without neither throwing an exception nor setting `PDOStatement::errorCode`
if many (~1000) query parameters are bound
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-241726@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/8773 Author: nagmat84 ### Description ### Summary If a query binds many (i.e. around 1000) parameters, the method PDOStatement::execute() fails and returns false. Even though PDO::ERRMODE_EXCEPTION is set as part of the PDO options no exception is thrown. PDOStatement::execute() neither sets PDOStatement::errorCode(). However, a subsequent fetchAll returns an empty array with zero query results. Note, that the bug can be worked around, if the binding are resolved manually. This mean if all placeholders '?' inside the query string are replaced by their actual value before the query is passed to PDOStatement::prepare(), then PDOStatement::execute() does not fail and a subsequent PDOStatement::fetchAll() returns the expected number of results. The issue has been reported by a couple of our users of https://github.com/LycheeOrg/Lychee. We have tracked it down to the PDO layer, i.e. it is not a bug in our code nor in the Laravel framework. A MWE which triggers the bug is located in https://github.com/LycheeOrg/MySQL1000Bug. The bug only occurs for a couple of users not everyone. But if the bug occurs for a specific setup, then the bug occurs deterministically. So far, we have seen bug reports from users with PHP 8.1.2 and 8.1.5 – 8.1.7. We haven't seen any bug reports for 8.0.x, but this doesn't mean that the bug might not exist there as well. Among the core developer team @querty287 has been able to reproduce the faulty behaviour on his development machine. As the bug only occurs for many query parameters and only for specific setups it smells like a memory corruption bug in the MySQL PDO code which is responsible for parameter binding. ### Steps to reproduce the problem 1. Checkout the repository https://github.com/LycheeOrg/MySQL1000Bug 2. Create a new MySQL/Maria DB 3. Load the included [MySQL dump](https://github.com/LycheeOrg/MySQL1000Bug/blob/master/mysql_1000_bug.sql) into the DB. 4. Make a copy config.php of the provided [config.php.example](https://github.com/LycheeOrg/MySQL1000Bug/blob/master/config.php.example) and adopt it to your DB settings. 5. Run the test script [./mysql_1000_bug](https://github.com/LycheeOrg/MySQL1000Bug/blob/master/mysql_1000_bug.php). #### Output if the bug occurs ``` Test #1 - Query without bindings bind_values() : bound 0 values in total select_query() : $statement->fetchAll returned 7380 results check_db_result() : Everything seems fine :-( Test #2 - Query with bindings bind_values() : binding value __OcYDO3i7Bm9MaCx5SWJj_D as string to placeholder 1 succeeded ... bind_values() : binding value Zzik4C_-V-WhyyYcn2QLlaEG as string to placeholder 1074 succeeded bind_values() : bound 1074 values in total select_query() : $statement->execute() failed without exception, oh, oh select_query() : $statement->execute() returned error: 00000 select_query() : $statement->execute() returned error info: array(3) { [0]=> string(5) "00000" [1]=> NULL [2]=> NULL } select_query() : $statement->fetchAll returned 0 results check_db_result : fetched wrong number of size variants; got 0, expected 7380 ``` #### Expected output if the bug does not occur ``` Test #1 - Query without bindings bind_values() : bound 0 values in total select_query() : $statement->fetchAll returned 7380 results check_db_result() : Everything seems fine :-( Test #2 - Query with bindings bind_values() : binding value __OcYDO3i7Bm9MaCx5SWJj_D as string to placeholder 1 succeeded ... bind_values() : binding value Zzik4C_-V-WhyyYcn2QLlaEG as string to placeholder 1074 succeeded bind_values() : bound 1074 values in total select_query() : $statement->fetchAll returned 7380 results check_db_result() : Everything seems fine :-( ``` ### Further information | | | |:----------------------------|:-----------------------| | **PHP version for which the bug has been observed:** | 8.1.2 and 8.1.5 – 8.1.7 | | **Downstream issue:** | https://github.com/LycheeOrg/Lychee/issues/1326 | | **MWE repo:** | https://github.com/LycheeOrg/MySQL1000Bug | ### PHP Version PHP 8.1.7 ### Operating System _No response_

« previous php.bugs (#241726) next »