Opened 8 years ago
Closed 5 years ago
#39053 closed enhancement (maybelater)
Add function `wp_validate_integer`
Reported by: | peterwilsoncc | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | |
Component: | General | Keywords: | has-patch has-unit-tests needs-refresh |
Focuses: | Cc: |
Description
WordPress validates integers in a number of locations, each time using specific code:
WP_Post::get_instance()
*_metadata_by_mid()
As filter_var
is not available in all installations, let's add an equivalent: wp_validate_integer()
.
Patch incoming.
Attachments (1)
Change History (11)
#2
in reply to:
↑ 1
;
follow-up:
↓ 3
@
8 years ago
- Keywords needs-refresh added
- Milestone changed from Awaiting Review to 4.8
Replying to voldemortensen:
My real question though, is what is the need for the
default
parameter? I can't see a reason someone would want anything but false if the thing being checked isn't an integer.
It might be preferable to return a WP_Error rather than false. I'll add that as a specific test case.
Mainly, I've included it to match the PHP signature.
Thanks for picking up the docblock changes needed. I'll fix them up.
#3
in reply to:
↑ 2
@
8 years ago
Replying to peterwilsoncc:
It might be preferable to return a WP_Error rather than false. I'll add that as a specific test case.
Mainly, I've included it to match the PHP signature.
Makes sense. I can agree with that.
#4
follow-up:
↓ 5
@
8 years ago
@dd32 you mentioned in passing elsewhere this may fail with 64 bit numbers on 32 bit systems. Do you have any suggestions on how to fix this.
if ( ! is_numeric( $var ) || floor( $var ) != $var )
is used currently used in core, so it will need to be removed if that's the problematic line.
#5
in reply to:
↑ 4
@
8 years ago
Replying to peterwilsoncc:
@dd32 you mentioned in passing elsewhere this may fail with 64 bit numbers on 32 bit systems. Do you have any suggestions on how to fix this.
if ( ! is_numeric( $var ) || floor( $var ) != $var )
is used currently used in core, so it will need to be removed if that's the problematic line.
I'm honestly not sure if it's an issue at all.
Even on 64bit PHP 9223372036854775808
is 1 larger than what will fit inside an int
, PHP automatically converts it to a float
in that case, and the above code will pass as expected.
However, if you attempt to cast it to an int (int)9223372036854775808
you'll get -9223372036854775808
as the value you're operating upon, which is highly unexpected - so don't cast things to (int)
..
#6
@
8 years ago
The only way to surface the type max size problem is to check for it and fail when it exceeds the limit.
PHP_INT_SIZE will hold the maximum size an Integer can have for each system. Silently converting/normalizing and moving on will cause unwanted and obscure problems. Breaking and notifying about the problem makes it something that can be reasoned about and a resolution to be implemented.
#7
@
8 years ago
Breaking and notifying about the problem makes it something that can be reasoned about and a resolution to be implemented.
This is exactly the reason for a function like this to exist, but integrating it into WordPress core will be tricky.
When would it actually get used?
On user POSTed values or GET query parameters? Do we use it again very late in $wpdb
before database writes occur? If all we want to do is make sure a numeric variable is within the boundaries of what's allowed inside a BIGINT(20) unsigned
database column, does it make sense to do that high-up in user-land or deep in the kernel?
If it's as a replacement for absint()
or intval()
, it may cause breakage if third-party code does not already discriminate between negative numbers and suddenly core changes the value mid-request.
We wouldn't want to use it everywhere, because function calls are slower than simple type-casts, and add to that the additional mathematical comparison logic against known large integers, and there's not a ton of value in repeatedly checking that every object's ID is a sane value.
#8
@
8 years ago
Related: @johnjamesjacoby did some research around large numbers in ticket 38203
I'm not overly worried about extra function calls as doing so is a micro-optimisation when WP could be optimised in more effective ways.
Using this in a way that breaks backward compat is a bigger concern.
#9
@
8 years ago
- Milestone changed from 4.8 to Future Release
Bumping this as there is no time to do properly before 4.8.
I've done some testing and multiplying a numeric string by 1 casts to either an integer for numbers below PHP_INT_MAX
, or a float for numbers above.
In terms of object IDs in core, which is where we'd use this most, I think having the correct value is more important than having the ideal type. It sure would be dandy to be able to make use of the BIG INTs we have in the database.
I've chatted about this with @joehoyle at length & I know he disagrees, it would be good to get others thoughts and push back.
👍 I like this.
Only a couple nitpicks, there's one misspelling
fiter_var
, and some doc block aligning issues.My real question though, is what is the need for the
default
parameter? I can't see a reason someone would want anything but false if the thing being checked isn't an integer.