Conversation
|
Why do you say this is a bug? IMHO PDO should not keep its previous bindings even if the new one fails. What makes you think that it should? Is it documented as such somewhere? Is there something I am misunderstanding here? |
|
I think easier fix is this: in PDOStatement::execute() And to fix UAF you can do: and in pdo_stmt.c:367-378 This is a very strange problem to encounter and very low priority to fix, but since you are trying to fix this already, I think this might be better. I have not tested this code above. |
3847ee1 to
027fb9d
Compare
|
The bug is the partial state: after the throw, the next execute() runs with the entries bound before it ( |
027fb9d to
75d1d56
Compare
75d1d56 to
4538af8
Compare
|
You can add also a test like this: which should throw under valgrind without this PR. And I agree that the bug isn't very impactful, so we don't have to backport it. |
PDOStatement::execute() destroyed bound_params before registering the entries of its array argument, so a failure part-way through (a value whose string conversion throws) left the entries registered so far in place, and a following execute() without arguments ran with them. Drop the partial table on failure instead. really_register_bound_param() now looks the table up only after converting the value, and raises the PDO_PARAM_EVT_ALLOC error after undoing its insert, so a __toString() or error handler that re-executes the statement no longer frees the table in use.
4538af8 to
03c997a
Compare
|
Added as a separate test in 03c997a. |
kamil-tekiela
left a comment
There was a problem hiding this comment.
I would wait with merging until the Windows test is fixed.
PDOStatement::execute() dropped the existing bindings before binding its array argument, so when an entry failed part-way through, for example a value whose string conversion throws, the entries bound so far stayed installed and the next execute() without arguments ran with them. The partial table is now dropped on failure. really_register_bound_param() looks the table up only after converting the value and raises the PDO_PARAM_EVT_ALLOC error after undoing its insert, so a __toString() or error handler that re-executes the statement no longer frees the table in use (verified under valgrind).