[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