ID: 49510 Updated by: sjo...@php.net Reported By: m dot kurzyna at crystalpoint dot pl Status: Assigned Bug Type: Filter related Operating System: Linux PHP Version: 5.3.0 Assigned To: pajoye New Comment:
Why do you think it is wrong that it returns null for an empty string? Previous Comments: ------------------------------------------------------------------------ [2009-09-10 08:53:11] m dot kurzyna at crystalpoint dot pl Actually it is broken even more then i initially reported because it also returns NULL for empty string: filter_var('',FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)) // got NULL, expected false The problem is in ext/filter/logical_filters.c(233) - the check is done by using string representation of zval being checked. For false value it's an empty string and the switch from line 244 doesn't cover this case (hence same result for false and empty string). Something along the lines of following patch should fix the problem: --- logical_filters.c 2009-06-10 21:01:17.000000000 +0200 +++ logical_filters.fixed.c 2009-09-10 10:48:59.953675880 +0200 @@ -242,6 +242,10 @@ * returns false for "0", "false", "off", "no", and "" * null otherwise. */ switch (len) { + case 0: + ret = 0; + break; + case 1: if (*str == '1') { ret = 1; On the side note: i was always wondering why (string)false == '' and not '0'? ------------------------------------------------------------------------ [2009-09-09 23:00:32] paj...@php.net This case sounds wrong: filter_var(false,FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got NULL, expected false I have to check back the code, but this case does not make sense to me. ------------------------------------------------------------------------ [2009-09-09 22:30:34] m dot kurzyna at crystalpoint dot pl If this is, as you say, intended behaviour then sorry, but it's broken by design. Although because of BC it'll never get fixed unfortunately so i'll just vent my frustration. In current state you have no way to use filters to *validate* boolean input (note that this is filter_validate_boolean not filter_sanitize_boolean - there is no such). As a sanitizer it's also broken though because real boolean values can't be used (or distinguished from error values when FILTER_NULL_ON_FAILURE is given) so you'd have to first check whether value is boolean and if not try to sanitize it to boolean using validating filter. It even sound broken. Also it's internally inconsistent. It works as expected for plain filtering: var_dump( filter_var(true,FILTER_VALIDATE_BOOLEAN), // true filter_var("true",FILTER_VALIDATE_BOOLEAN), // true filter_var(1,FILTER_VALIDATE_BOOLEAN), // true filter_var("1",FILTER_VALIDATE_BOOLEAN), // true filter_var("on",FILTER_VALIDATE_BOOLEAN), // true filter_var("yes",FILTER_VALIDATE_BOOLEAN) // true ); var_dump( filter_var(false,FILTER_VALIDATE_BOOLEAN), // false filter_var("false",FILTER_VALIDATE_BOOLEAN), // false filter_var(0,FILTER_VALIDATE_BOOLEAN), // false filter_var("0",FILTER_VALIDATE_BOOLEAN), // false filter_var("off",FILTER_VALIDATE_BOOLEAN), // false filter_var("no",FILTER_VALIDATE_BOOLEAN) // false ); var_dump( filter_var(7,FILTER_VALIDATE_BOOLEAN), // false filter_var("garbage",FILTER_VALIDATE_BOOLEAN) // false ); But fails to keep consistency when i try to distinguish whether value is "boolean" or not witch should be the sole role of *VALIDATE* filter: var_dump( filter_var(true,FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got true, expected true filter_var("true",FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got true, expected true filter_var(1,FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got true, expected true filter_var("1",FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got true, expected true filter_var("on",FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got true, expected true filter_var("yes",FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)) // got true, expected true ); var_dump( filter_var(false,FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got NULL, expected false filter_var("false",FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got false, expected false filter_var(0,FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got false, expected false filter_var("0",FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got false, expected false filter_var("off",FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got false, expected false filter_var("no",FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)) // got false, expected false ); var_dump( filter_var(7,FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)), // got null, expected null filter_var("garbage",FILTER_VALIDATE_BOOLEAN,array('flags'=>FILTER_NULL_ON_FAILURE)) // got null, expected null ); See that validating true works as expected so dunno why false should work differently. Also the "little bit confusing" part of false being non boolean is just plain wrong. In summary - please rethink this behaviour or at least fix the documentation by a) giving above example of all results (to show what is really to be expected) and b) state this is a validate filter by mistake but will stay like this because of BC concerns. ------------------------------------------------------------------------ [2009-09-09 19:55:33] sjo...@php.net This is exactly according to the documentation: If FILTER_NULL_ON_FAILURE is set, FALSE is returned only for "0", "false", "off", "no", and "", and NULL is returned for all non-boolean values. Note that "false" is in the list, but false is not. That is, the string "false" will give a result, the boolean false will return null. "Non-boolean" makes this a little bit confusing. Note that the goal here is to convert a string to a boolean. Because false is not a string, filter_var does not consider it valid input. ------------------------------------------------------------------------ [2009-09-09 11:25:29] m dot kurzyna at crystalpoint dot pl Description: ------------ filter_var() when validating (boolean)false with FILTER_NULL_ON_FAILURE returns null instead of false. Reproduce code: --------------- var_dump( filter_var(false, FILTER_VALIDATE_BOOLEAN, array("flags" => FILTER_NULL_ON_FAILURE) ) ); Expected result: ---------------- false Actual result: -------------- null ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=49510&edit=1