I need to talk about types here, so just to be clear when I say:
- true/false - I mean the boolean values true and false
- 'true'/'false' - I mean the strings 'true' and 'false'
- 0/1 - I mean the integers 0 and 1
- '0'/'1' - I mean the strings '0' and '1'
When we clean_param with a PARAM_BOOL, we do this:
Which produces this mapping:
Then in validate_param we do this:
Where $param is the original param, and $cleaned is the cleaned one. This is really broken with PARAM_BOOL. For example if you pass 'yes', then clean_param will produce 1, and of course 'yes' !== 1
The worst case (and the case that I personally ran in to) is when boolean false is passed. When false is cast to a string, we get the empty string, but clean_param returns 0 so we end up comparing '' to 0, and it flakes out. Small snippet to demonstrate: