[wp-trac] [WordPress Trac] #41944: Add %u support to wpdb->prepare
WordPress Trac
noreply at wordpress.org
Thu Sep 21 14:18:13 UTC 2017
#41944: Add %u support to wpdb->prepare
--------------------------+------------------------------
Reporter: charlestonsw | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Database | Version: 4.8.2
Severity: normal | Resolution:
Keywords: | Focuses:
--------------------------+------------------------------
Comment (by soulseekah):
Again, there is no unsigned int in PHP.
The %u is there to convert signed integers to unsigned ones for various
lower-level (think binary protocols mostly) purposes.
Observe the following behavior:
{{{
> printf( '%u', -1 );
18446744073709551615
}}}
See how we got a number printed that is twice as large as PHP_MAX_INT? But
you can never store that in a variable of type <code>integer</code>:
{{{
> echo (int)sprintf( '%u', -1 );
9223372036854775807
}}}
Which is just an overflow. There no unsigned integer type in PHP, hope
this makes sense. Another overflow observation:
{{
> echo 18446744073709551615;
1.844674407371E+19
> echo gettype( 18446744073709551615 );
double
}}
But back to unsigned ints. So what you would have to do to make it sort of
work is to sent a negative number to the prepare function:
<code>$wpdb->prepare( "%u", -595231 )</code> to send a value larger than
PHP_MAX_INT to the database. Even then, the prepare method is simply
converting everything to a string. So you're not actually sending a number
over the line but a string.
So in order to make it work, you'd need some sort of function that
converts a numeric string that is larger than PHP_MAX_INT into a signed
counterpart that is smaller than (PHP_MAX_INT * 2) and sends a negative
number into the prepare method just to get a string back that you send to
the database. Why not just sent the numeric string into an %s placeholder
to begin with?
The same with GMP/bcmath libraries.
So I invite you to show me a snippet of code that gets a large (>
PHP_MAX_INT) numeric value from say <code>$_GET['id']</code> and does a
<code>SELECT * FROM wp_posts WHERE ID = %u</code> on it.
{{{
$post_id = $_GET['id'];
$wpdb->query( $wpdb->prepare( 'SELECT * FROM wp_posts WHERE ID = %u',
$post_id ) );
}}}
Type coercion in PHP will try to set it as int, observe:
{{{
> printf( '%u', '18446744073709551615' );
9223372036854775807
}}}
Overflow. Any ideas?
--
Ticket URL: <https://core.trac.wordpress.org/ticket/41944#comment:4>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list