From 6eaa56f3d45ffa08ff73ec748b75ee0ee14e5e23 Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Fri, 26 Aug 2016 19:08:23 +0000 Subject: [PATCH] Don't improperly cast IDs when fetching post, user, or term objects. Blindly casting passed IDs to integers can generate false positives when the ID is cast to `1`. Props deeptiboddapati. Fixes #37738. git-svn-id: https://develop.svn.wordpress.org/trunk@38381 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-comment.php | 5 +- src/wp-includes/class-wp-post.php | 6 +- src/wp-includes/class-wp-term.php | 5 +- tests/phpunit/tests/comment/wpComment.php | 102 +++++++++++++++++++ tests/phpunit/tests/post/wpPost.php | 100 +++++++++++++++++++ tests/phpunit/tests/term/wpTerm.php | 113 ++++++++++++++++++++++ 6 files changed, 325 insertions(+), 6 deletions(-) create mode 100644 tests/phpunit/tests/comment/wpComment.php create mode 100644 tests/phpunit/tests/post/wpPost.php create mode 100644 tests/phpunit/tests/term/wpTerm.php diff --git a/src/wp-includes/class-wp-comment.php b/src/wp-includes/class-wp-comment.php index 0e9f88a352..80ef9bb1d3 100644 --- a/src/wp-includes/class-wp-comment.php +++ b/src/wp-includes/class-wp-comment.php @@ -191,11 +191,12 @@ final class WP_Comment { public static function get_instance( $id ) { global $wpdb; - $comment_id = (int) $id; - if ( ! $comment_id ) { + if ( ! is_numeric( $id ) || $id != floor( $id ) || ! $id ) { return false; } + $comment_id = (int) $id; + $_comment = wp_cache_get( $comment_id, 'comment' ); if ( ! $_comment ) { diff --git a/src/wp-includes/class-wp-post.php b/src/wp-includes/class-wp-post.php index 5904e588d0..a21776f192 100644 --- a/src/wp-includes/class-wp-post.php +++ b/src/wp-includes/class-wp-post.php @@ -210,9 +210,11 @@ final class WP_Post { public static function get_instance( $post_id ) { global $wpdb; - $post_id = (int) $post_id; - if ( ! $post_id ) + if ( ! is_numeric( $post_id ) || $post_id != floor( $post_id ) || ! $post_id ) { return false; + } + + $post_id = (int) $post_id; $_post = wp_cache_get( $post_id, 'posts' ); diff --git a/src/wp-includes/class-wp-term.php b/src/wp-includes/class-wp-term.php index 8eb87efbe0..6cb4a15bd8 100644 --- a/src/wp-includes/class-wp-term.php +++ b/src/wp-includes/class-wp-term.php @@ -125,11 +125,12 @@ final class WP_Term { public static function get_instance( $term_id, $taxonomy = null ) { global $wpdb; - $term_id = (int) $term_id; - if ( ! $term_id ) { + if ( ! is_numeric( $term_id ) || $term_id != floor( $term_id ) || ! $term_id ) { return false; } + $term_id = (int) $term_id; + $_term = wp_cache_get( $term_id, 'terms' ); // If there isn't a cached version, hit the database. diff --git a/tests/phpunit/tests/comment/wpComment.php b/tests/phpunit/tests/comment/wpComment.php new file mode 100644 index 0000000000..5769fa3ee7 --- /dev/null +++ b/tests/phpunit/tests/comment/wpComment.php @@ -0,0 +1,102 @@ +insert( $wpdb->comments, array( + 'comment_ID' => 1, + ) ); + + clean_comment_cache( 1 ); + } + + self::$comment_id = self::factory()->comment->create(); + } + + public static function wpTearDownAfterClass() { + wp_delete_comment( 1, true ); + wp_delete_comment( self::$comment_id, true ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_work_for_numeric_string() { + $found = WP_Comment::get_instance( (string) self::$comment_id ); + + $this->assertEquals( self::$comment_id, $found->comment_ID ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_negative_number() { + $found = WP_Comment::get_instance( -self::$comment_id ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_non_numeric_string() { + $found = WP_Comment::get_instance( 'abc' ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_bool() { + $found = WP_Comment::get_instance( true ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_succeed_for_float_that_is_equal_to_post_id() { + $found = WP_Comment::get_instance( 1.0 ); + + $this->assertEquals( 1, $found->comment_ID ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_float() { + $found = WP_Comment::get_instance( 1.6 ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_array() { + $found = WP_Comment::get_instance( array( 1 ) ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_class() { + $class = new stdClass(); + $found = WP_Comment::get_instance( $class ); + + $this->assertFalse( $found ); + } +} diff --git a/tests/phpunit/tests/post/wpPost.php b/tests/phpunit/tests/post/wpPost.php new file mode 100644 index 0000000000..2345c217b5 --- /dev/null +++ b/tests/phpunit/tests/post/wpPost.php @@ -0,0 +1,100 @@ +insert( $wpdb->posts, array( + 'ID' => 1, + 'post_title' => 'Post 1', + ) ); + } + + self::$post_id = self::factory()->post->create(); + } + + public static function wpTearDownAfterClass() { + wp_delete_post( 1, true ); + wp_delete_post( self::$post_id, true ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_work_for_numeric_string() { + $found = WP_Post::get_instance( (string) self::$post_id ); + + $this->assertSame( self::$post_id, $found->ID ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_negative_number() { + $found = WP_Post::get_instance( -self::$post_id ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_non_numeric_string() { + $found = WP_Post::get_instance( 'abc' ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_bool() { + $found = WP_Post::get_instance( true ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_succeed_for_float_that_is_equal_to_post_id() { + $found = WP_Post::get_instance( 1.0 ); + + $this->assertSame( 1, $found->ID ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_float() { + $found = WP_Post::get_instance( 1.6 ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_array() { + $found = WP_Post::get_instance( array( 1 ) ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_class() { + $class = new stdClass(); + $found = WP_Post::get_instance( $class ); + + $this->assertFalse( $found ); + } +} diff --git a/tests/phpunit/tests/term/wpTerm.php b/tests/phpunit/tests/term/wpTerm.php new file mode 100644 index 0000000000..5ce7023d4e --- /dev/null +++ b/tests/phpunit/tests/term/wpTerm.php @@ -0,0 +1,113 @@ +insert( $wpdb->terms, array( + 'term_id' => 1, + ) ); + + $wpdb->insert( $wpdb->term_taxonomy, array( + 'term_id' => 1, + 'taxonomy' => 'wptests_tax', + ) ); + + clean_term_cache( 1, 'wptests_tax' ); + } + + self::$term_id = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax' ) ); + } + + public static function wpTearDownAfterClass() { + wp_delete_term( 1, 'wptests_tax' ); + wp_delete_term( self::$term_id, 'wptests_tax' ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_work_for_numeric_string() { + $found = WP_Term::get_instance( (string) self::$term_id ); + + $this->assertSame( self::$term_id, $found->term_id ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_negative_number() { + $found = WP_Term::get_instance( -self::$term_id ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_non_numeric_string() { + $found = WP_Term::get_instance( 'abc' ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_bool() { + $found = WP_Term::get_instance( true ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_succeed_for_float_that_is_equal_to_post_id() { + $found = WP_Term::get_instance( 1.0 ); + + $this->assertSame( 1, $found->term_id ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_float() { + $found = WP_Term::get_instance( 1.6 ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_array() { + $found = WP_Term::get_instance( array( 1 ) ); + + $this->assertFalse( $found ); + } + + /** + * @ticket 37738 + */ + public function test_get_instance_should_fail_for_class() { + $class = new stdClass(); + $found = WP_Term::get_instance( $class ); + + $this->assertFalse( $found ); + } +}