Page MenuHomePhabricator
Paste P109

Answer to bug hunt problem
ActivePublic

Authored by stwalkerster on Feb 8 2017, 10:59 AM.
OK, so the answer to P108 lies in the fact it's a parameterised query using positional parameters.
The key points to this are the limit() call and how it interacts with the fetchByParameter() call.
Most of the code given can be ignored initially, so let's direct our focus immediately to the fetchByParameter() definition.
We begin by building the query with the provided where clause snippet, which will result in the following queries:
SELECT /* SearchHelper */ COUNT(*) FROM request origin WHERE 1 = 1 AND status = ?;
SELECT /* SearchHelper */ origin.* FROM request origin WHERE 1 = 1 AND status = ? LIMIT ?;
Immediately, you can see that the meaning of the last parameter has in fact changed - a point we rely on later within the fetchByParameter call().
Following this, we take the parameter list, copy it, and add each entry of the passed array to it in turn and execute the query, such that if we had array(2,3,4), and passed this function array('a','b','c'), we'd end up with three calls of array(2,3,4,'a'), array(2,3,4,'b'), and array(2,3,4,'c').
This would work well when there's no limit clause, but in fact what actually happens is we get the original parameters of array(2,3,4), apply the where clause, then apply the limit. As we don't apply the parameter of the where clause to the parameter list, before applying the limit, the parameter from the limit is put in the position for the where clause, and we're actually swapping out the parameter for the limit, not the where clause.
As the limit parameters take effect on the count query too, this also ensures the count retrieves no results.