Make WordPress Core


Ignore:
Timestamp:
11/14/2014 09:27:17 PM (12 years ago)
Author:
pento
Message:

When creating a post containing emoji, the post can be saved incorrectly if MySQL isn't using a character set that supports emoji.

This change prevents the save from occurring, so it can be handled correctly in the UI.

See #21212.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/db.php

    r30320 r30345  
    1515
    1616        /**
     17         * Our special WPDB
     18         * @var resource
     19         */
     20        protected static $_wpdb;
     21
     22        public static function setUpBeforeClass() {
     23                self::$_wpdb = new wpdb_exposed_methods_for_testing();
     24        }
     25
     26        /**
    1727         * Set up the test fixture
    1828         */
     
    2737         */
    2838        public function tearDown() {
     39                remove_filter( 'query', array( $this, 'query_filter' ) );
    2940                parent::tearDown();
    30                 remove_filter( 'query', array( $this, 'query_filter' ) );
    3141        }
    3242
     
    225235
    226236        /**
     237         * @ticket 21212
     238         */
     239        function test_wpdb_actually_protected_properties() {
     240                global $wpdb;
     241
     242                $new_meta = "HAHA I HOPE THIS DOESN'T WORK";
     243
     244                $col_meta = $wpdb->col_meta;
     245                $wpdb->col_meta = $new_meta;
     246
     247                $this->assertNotEquals( $col_meta, $new_meta );
     248                $this->assertEquals( $col_meta, $wpdb->col_meta );
     249        }
     250
     251        /**
    227252         * @ticket 18510
    228253         */
     
    494519                $wpdb->suppress_errors( $suppress );
    495520        }
     521
     522        /**
     523         * @ticket 21212
     524         */
     525        function data_get_table_from_query() {
     526                $table = 'a_test_table_name';
     527
     528                $queries = array(
     529                        // Basic
     530                        "SELECT * FROM $table",
     531                        "SELECT * FROM `$table`",
     532
     533                        "INSERT $table",
     534                        "INSERT IGNORE $table",
     535                        "INSERT IGNORE INTO $table",
     536                        "INSERT INTO $table",
     537                        "INSERT LOW_PRIORITY $table",
     538                        "INSERT DELAYED $table",
     539                        "INSERT HIGH_PRIORITY $table",
     540                        "INSERT LOW_PRIORITY IGNORE $table",
     541                        "INSERT LOW_PRIORITY INTO $table",
     542                        "INSERT LOW_PRIORITY IGNORE INTO $table",
     543
     544                        "REPLACE $table",
     545                        "REPLACE INTO $table",
     546                        "REPLACE LOW_PRIORITY $table",
     547                        "REPLACE DELAYED $table",
     548                        "REPLACE LOW_PRIORITY INTO $table",
     549
     550                        "UPDATE LOW_PRIORITY $table",
     551                        "UPDATE LOW_PRIORITY IGNORE $table",
     552
     553                        "DELETE $table",
     554                        "DELETE IGNORE $table",
     555                        "DELETE IGNORE FROM $table",
     556                        "DELETE FROM $table",
     557                        "DELETE LOW_PRIORITY $table",
     558                        "DELETE QUICK $table",
     559                        "DELETE IGNORE $table",
     560                        "DELETE LOW_PRIORITY FROM $table",
     561
     562                        // STATUS
     563                        "SHOW TABLE STATUS LIKE '$table'",
     564                        "SHOW TABLE STATUS WHERE NAME='$table'",
     565
     566                        "SHOW TABLES LIKE '$table'",
     567                        "SHOW FULL TABLES LIKE '$table'",
     568                        "SHOW TABLES WHERE NAME='$table'",
     569
     570                        // Extended
     571                        "EXPLAIN SELECT * FROM $table",
     572                        "EXPLAIN EXTENDED SELECT * FROM $table",
     573                        "EXPLAIN EXTENDED SELECT * FROM `$table`",
     574
     575                        "DESCRIBE $table",
     576                        "DESC $table",
     577                        "EXPLAIN $table",
     578                        "HANDLER $table",
     579
     580                        "LOCK TABLE $table",
     581                        "LOCK TABLES $table",
     582                        "UNLOCK TABLE $table",
     583
     584                        "RENAME TABLE $table",
     585                        "OPTIMIZE TABLE $table",
     586                        "BACKUP TABLE $table",
     587                        "RESTORE TABLE $table",
     588                        "CHECK TABLE $table",
     589                        "CHECKSUM TABLE $table",
     590                        "ANALYZE TABLE $table",
     591                        "REPAIR TABLE $table",
     592
     593                        "TRUNCATE $table",
     594                        "TRUNCATE TABLE $table",
     595
     596                        "CREATE TABLE $table",
     597                        "CREATE TEMPORARY TABLE $table",
     598                        "CREATE TABLE IF NOT EXISTS $table",
     599
     600                        "ALTER TABLE $table",
     601                        "ALTER IGNORE TABLE $table",
     602
     603                        "DROP TABLE $table",
     604                        "DROP TABLE IF EXISTS $table",
     605
     606                        "CREATE INDEX foo(bar(20)) ON $table",
     607                        "CREATE UNIQUE INDEX foo(bar(20)) ON $table",
     608                        "CREATE FULLTEXT INDEX foo(bar(20)) ON $table",
     609                        "CREATE SPATIAL INDEX foo(bar(20)) ON $table",
     610
     611                        "DROP INDEX foo ON $table",
     612
     613                        "LOAD DATA INFILE 'wp.txt' INTO TABLE $table",
     614                        "LOAD DATA LOW_PRIORITY INFILE 'wp.txt' INTO TABLE $table",
     615                        "LOAD DATA CONCURRENT INFILE 'wp.txt' INTO TABLE $table",
     616                        "LOAD DATA LOW_PRIORITY LOCAL INFILE 'wp.txt' INTO TABLE $table",
     617                        "LOAD DATA INFILE 'wp.txt' REPLACE INTO TABLE $table",
     618                        "LOAD DATA INFILE 'wp.txt' IGNORE INTO TABLE $table",
     619
     620                        "GRANT ALL ON TABLE $table",
     621                        "REVOKE ALL ON TABLE $table",
     622
     623                        "SHOW COLUMNS FROM $table",
     624                        "SHOW FULL COLUMNS FROM $table",
     625                        "SHOW CREATE TABLE $table",
     626                        "SHOW INDEX FROM $table",
     627                );
     628
     629                foreach ( $queries as &$query ) {
     630                        $query = array( $query, $table );
     631                }
     632                return $queries;
     633        }
     634
     635        /**
     636         * @dataProvider data_get_table_from_query
     637         * @ticket 21212
     638         */
     639        function test_get_table_from_query( $query, $table ) {
     640                $this->assertEquals( $table, self::$_wpdb->get_table_from_query( $query ) );
     641        }
     642
     643        function data_get_table_from_query_false() {
     644                $table = 'a_test_table_name';
     645                return array(
     646                        array( "LOL THIS ISN'T EVEN A QUERY $table" ),
     647                );
     648        }
     649
     650        /**
     651         * @dataProvider data_get_table_from_query_false
     652         * @ticket 21212
     653         */
     654        function test_get_table_from_query_false( $query ) {
     655                $this->assertFalse( self::$_wpdb->get_table_from_query( $query ) );
     656        }
     657
     658        /**
     659         * @ticket 21212
     660         */
     661        function data_process_field_formats() {
     662                $core_db_fields_no_format_specified = array(
     663                        array( 'post_content' => 'foo', 'post_parent' => 0 ),
     664                        null,
     665                        array(
     666                                'post_content' => array( 'value' => 'foo', 'format' => '%s' ),
     667                                'post_parent' => array( 'value' => 0, 'format' => '%d' ),
     668                        )
     669                );
     670
     671                $core_db_fields_formats_specified = array(
     672                        array( 'post_content' => 'foo', 'post_parent' => 0 ),
     673                        array( '%d', '%s' ), // These override core field_types
     674                        array(
     675                                'post_content' => array( 'value' => 'foo', 'format' => '%d' ),
     676                                'post_parent' => array( 'value' => 0, 'format' => '%s' ),
     677                        )
     678                );
     679
     680                $misc_fields_no_format_specified = array(
     681                        array( 'this_is_not_a_core_field' => 'foo', 'this_is_not_either' => 0 ),
     682                        null,
     683                        array(
     684                                'this_is_not_a_core_field' => array( 'value' => 'foo', 'format' => '%s' ),
     685                                'this_is_not_either' => array( 'value' => 0, 'format' => '%s' ),
     686                        )
     687                );
     688
     689                $misc_fields_formats_specified = array(
     690                        array( 'this_is_not_a_core_field' => 0, 'this_is_not_either' => 1.2 ),
     691                        array( '%d', '%f' ),
     692                        array(
     693                                'this_is_not_a_core_field' => array( 'value' => 0, 'format' => '%d' ),
     694                                'this_is_not_either' => array( 'value' => 1.2, 'format' => '%f' ),
     695                        )
     696                );
     697
     698                $misc_fields_insufficient_formats_specified = array(
     699                        array( 'this_is_not_a_core_field' => 0, 'this_is_not_either' => 's', 'nor_this' => 1 ),
     700                        array( '%d', '%s' ), // The first format is used for the third
     701                        array(
     702                                'this_is_not_a_core_field' => array( 'value' => 0, 'format' => '%d' ),
     703                                'this_is_not_either' => array( 'value' => 's', 'format' => '%s' ),
     704                                'nor_this' => array( 'value' => 1, 'format' => '%d' ),
     705                        )
     706                );
     707
     708                $vars = get_defined_vars();
     709                // Push the variable name onto the end for assertSame $message
     710                foreach ( $vars as $var_name => $var ) {
     711                        $vars[ $var_name ][] = $var_name;
     712                }
     713                return array_values( $vars );
     714        }
     715
     716        /**
     717         * @dataProvider data_process_field_formats
     718         * @ticket 21212
     719         */
     720        function test_process_field_formats( $data, $format, $expected, $message ) {
     721                $actual = self::$_wpdb->process_field_formats( $data, $format );
     722                $this->assertSame( $expected, $actual, $message );
     723        }
     724
     725        /**
     726         * @ticket 21212
     727         */
     728        function test_process_fields() {
     729                global $wpdb;
     730                $data = array( 'post_content' => '¡foo foo foo!' );
     731                $expected = array(
     732                        'post_content' => array(
     733                                'value' => '¡foo foo foo!',
     734                                'format' => '%s',
     735                                'charset' => $wpdb->charset,
     736                                'ascii' => false,
     737                        )
     738                );
     739
     740                $this->assertSame( $expected, self::$_wpdb->process_fields( $wpdb->posts, $data, null ) );
     741        }
     742
     743        /**
     744         * @ticket 21212
     745         * @depends test_process_fields
     746         */
     747        function test_process_fields_on_nonexistent_table( $data ) {
     748                self::$_wpdb->suppress_errors( true );
     749                $data = array( 'post_content' => '¡foo foo foo!' );
     750                $this->assertFalse( self::$_wpdb->process_fields( 'nonexistent_table', $data, null ) );
     751                self::$_wpdb->suppress_errors( false );
     752        }
     753
     754        /**
     755         * @ticket 21212
     756         */
     757        function test_pre_get_table_charset_filter() {
     758                add_filter( 'pre_get_table_charset', array( $this, 'filter_pre_get_table_charset' ), 10, 2 );
     759                $charset = self::$_wpdb->get_table_charset( 'some_table' );
     760                remove_filter( 'pre_get_table_charset', array( $this, 'filter_pre_get_table_charset' ), 10 );
     761
     762                $this->assertEquals( $charset, 'fake_charset' );
     763        }
     764        function filter_pre_get_table_charset( $charset, $table ) {
     765                return 'fake_charset';
     766        }
     767
     768        /**
     769         * @ ticket 21212
     770         */
     771        function test_pre_get_col_charset_filter() {
     772                add_filter( 'pre_get_col_charset', array( $this, 'filter_pre_get_col_charset' ), 10, 3 );
     773                $charset = self::$_wpdb->get_col_charset( 'some_table', 'some_col' );
     774                remove_filter( 'pre_get_col_charset', array( $this, 'filter_pre_get_col_charset' ), 10 );
     775
     776                $this->assertEquals( $charset, 'fake_col_charset' );
     777        }
     778        function filter_pre_get_col_charset( $charset, $table, $column ) {
     779                return 'fake_col_charset';
     780        }
    496781}
     782
     783/**
     784 * Special class for exposing protected wpdb methods we need to access
     785 */
     786class wpdb_exposed_methods_for_testing extends wpdb {
     787        public function __construct() {
     788                global $wpdb;
     789                $this->dbh = $wpdb->dbh;
     790                $this->use_mysqli = $wpdb->use_mysqli;
     791                $this->ready = true;
     792                $this->field_types = $wpdb->field_types;
     793                $this->charset = $wpdb->charset;
     794        }
     795
     796        public function __call( $name, $arguments ) {
     797                return call_user_func_array( array( $this, $name ), $arguments );
     798        }
     799}
Note: See TracChangeset for help on using the changeset viewer.