Make WordPress Core

Opened 8 years ago

Closed 5 years ago

#39053 closed enhancement (maybelater)

Add function `wp_validate_integer`

Reported by: peterwilsoncc's profile 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)

39053.diff (4.2 KB) - added by peterwilsoncc 8 years ago.

Download all attachments as: .zip

Change History (11)

@peterwilsoncc
8 years ago

#1 follow-up: @voldemortensen
8 years ago

👍 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.

#2 in reply to: ↑ 1 ; follow-up: @peterwilsoncc
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 @voldemortensen
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: @peterwilsoncc
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 @dd32
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)..

ref: http://php.net/manual/en/language.types.integer.php

#6 @jipmoors
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 @johnjamesjacoby
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.

Last edited 8 years ago by johnjamesjacoby (previous) (diff)

#8 @peterwilsoncc
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 @peterwilsoncc
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.

#10 @peterwilsoncc
5 years ago

  • Milestone Future Release deleted
  • Resolution set to maybelater
  • Status changed from new to closed

Closing this due to lack of traction. Unsure it archives the intent for validating object IDs.

Note: See TracTickets for help on using tickets.