WordPress.org

Make WordPress Core

Ticket #21212: 21212-utf8mb4.5.diff

File 21212-utf8mb4.5.diff, 9.6 KB (added by pento, 5 years ago)
  • src/wp-admin/includes/schema.php

     
    5151 slug varchar(200) NOT NULL default '',
    5252 term_group bigint(10) NOT NULL default 0,
    5353 PRIMARY KEY  (term_id),
    54  KEY slug (slug),
    55  KEY name (name)
     54 KEY slug (slug(191)),
     55 KEY name (name(191))
    5656) $charset_collate;
    5757CREATE TABLE $wpdb->term_taxonomy (
    5858 term_taxonomy_id bigint(20) unsigned NOT NULL auto_increment,
     
    7979  meta_value longtext,
    8080  PRIMARY KEY  (meta_id),
    8181  KEY comment_id (comment_id),
    82   KEY meta_key (meta_key)
     82  KEY meta_key (meta_key(191))
    8383) $charset_collate;
    8484CREATE TABLE $wpdb->comments (
    8585  comment_ID bigint(20) unsigned NOT NULL auto_increment,
     
    136136  meta_value longtext,
    137137  PRIMARY KEY  (meta_id),
    138138  KEY post_id (post_id),
    139   KEY meta_key (meta_key)
     139  KEY meta_key (meta_key(191))
    140140) $charset_collate;
    141141CREATE TABLE $wpdb->posts (
    142142  ID bigint(20) unsigned NOT NULL auto_increment,
     
    163163  post_mime_type varchar(100) NOT NULL default '',
    164164  comment_count bigint(20) NOT NULL default '0',
    165165  PRIMARY KEY  (ID),
    166   KEY post_name (post_name),
     166  KEY post_name (post_name(191)),
    167167  KEY type_status_date (post_type,post_status,post_date,ID),
    168168  KEY post_parent (post_parent),
    169169  KEY post_author (post_author)
     
    213213  meta_value longtext,
    214214  PRIMARY KEY  (umeta_id),
    215215  KEY user_id (user_id),
    216   KEY meta_key (meta_key)
     216  KEY meta_key (meta_key(191))
    217217) $charset_collate;\n";
    218218
    219219        // Global tables
     
    261261  domain varchar(200) NOT NULL default '',
    262262  path varchar(100) NOT NULL default '',
    263263  PRIMARY KEY  (id),
    264   KEY domain (domain,path)
     264  KEY domain (domain(140),path(51))
    265265) $charset_collate;
    266266CREATE TABLE $wpdb->sitemeta (
    267267  meta_id bigint(20) NOT NULL auto_increment,
     
    269269  meta_key varchar(255) default NULL,
    270270  meta_value longtext,
    271271  PRIMARY KEY  (meta_id),
    272   KEY meta_key (meta_key),
     272  KEY meta_key (meta_key(191)),
    273273  KEY site_id (site_id)
    274274) $charset_collate;
    275275CREATE TABLE $wpdb->signups (
     
    288288  KEY activation_key (activation_key),
    289289  KEY user_email (user_email),
    290290  KEY user_login_email (user_login,user_email),
    291   KEY domain_path (domain,path)
     291  KEY domain_path (domain(140),path(51))
    292292) $charset_collate;";
    293293
    294294        switch ( $scope ) {
  • src/wp-admin/includes/upgrade.php

     
    519519        if ( $wp_current_db_version < 29630 )
    520520                upgrade_400();
    521521
     522        if ( $wp_current_db_version < 30134 )
     523                upgrade_420();
     524
    522525        maybe_disable_link_manager();
    523526
    524527        maybe_disable_automattic_widgets();
     
    14071410}
    14081411
    14091412/**
     1413 * Execute changes made in WordPress 4.2.0.
     1414 *
     1415 * @since 4.2.0
     1416 */
     1417function upgrade_420() {
     1418        global $wp_current_db_version, $wpdb;
     1419
     1420        if ( $wp_current_db_version < 30134 && $wpdb->charset === 'utf8mb4' ) {
     1421                if ( is_multisite() ) {
     1422                        $tables = $wpdb->tables;
     1423                } else {
     1424                        $tables = array_merge( $wpdb->tables, $wpdb->global_tables );
     1425                }
     1426
     1427                foreach ( $tables as $table ) {
     1428                        $results = $wpdb->get_results( "SHOW FULL COLUMNS FROM `{$wpdb->$table}`" );
     1429                        if ( ! $results ) {
     1430                                continue;
     1431                        }
     1432
     1433                        foreach ( $results as $column ) {
     1434                                if ( $column->Collation && 'utf8' !== $column->Collation ) {
     1435                                        // Don't upgrade tables that have non-utf8 columns
     1436                                        continue 2;
     1437                                }
     1438                        }
     1439
     1440                        $wpdb->query( "ALTER TABLE {$wpdb->$table} CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" );
     1441                }
     1442        }
     1443}
     1444
     1445/**
    14101446 * Executes network-level upgrade routines.
    14111447 *
    14121448 * @since 3.0.0
     
    15021538                        update_site_option( 'illegal_names', $illegal_names );
    15031539                }
    15041540        }
     1541
     1542        // 4.2
     1543        if ( $wp_current_db_version < 30134 && $wpdb->charset === 'utf8mb4') {
     1544                $tables = array_merge( $wpdb->ms_global_tables, $wpdb->global_tables );
     1545
     1546                foreach ( $tables as $table ) {
     1547                        $wpdb->query( "ALTER TABLE {$wpdb->$table} CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" );
     1548                }
     1549        }
    15051550}
    15061551
    15071552//
     
    22842329                // dbDelta() can recreate but can't drop the index.
    22852330                $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug" );
    22862331        }
     2332
     2333        if ( $wp_current_db_version < 30134 ) {
     2334                // We need to alter some indices
     2335                $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key" );
     2336                $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug" );
     2337                $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX name" );
     2338                $wpdb->query( "ALTER TABLE $wpdb->commentmeta DROP INDEX meta_key" );
     2339                $wpdb->query( "ALTER TABLE $wpdb->postmeta DROP INDEX meta_key" );
     2340                $wpdb->query( "ALTER TABLE $wpdb->posts DROP INDEX post_name" );
     2341        }
    22872342}
    22882343
    22892344/**
  • src/wp-admin/setup-config.php

     
    280280                        case 'DB_HOST'     :
    281281                                $config_file[ $line_num ] = "define('" . $constant . "'," . $padding . "'" . addcslashes( constant( $constant ), "\\'" ) . "');\r\n";
    282282                                break;
     283                        case 'DB_CHARSET'  :
     284                                if ( 'utf8mb4' === $wpdb->charset || ( ! $wpdb->charset && $wpdb->has_cap( 'utf8mb4' ) ) ) {
     285                                        $config_file[ $line_num ] = "define('" . $constant . "'," . $padding . "'utf8mb4');\r\n";
     286                                }
     287                                break;
    283288                        case 'AUTH_KEY'         :
    284289                        case 'SECURE_AUTH_KEY'  :
    285290                        case 'LOGGED_IN_KEY'    :
  • src/wp-includes/version.php

     
    1111 *
    1212 * @global int $wp_db_version
    1313 */
    14 $wp_db_version = 30133;
     14$wp_db_version = 30134;
    1515
    1616/**
    1717 * Holds the TinyMCE version
  • src/wp-includes/wp-db.php

     
    624624                        }
    625625                }
    626626
    627                 $this->init_charset();
    628 
    629627                $this->dbuser = $dbuser;
    630628                $this->dbpassword = $dbpassword;
    631629                $this->dbname = $dbname;
     
    727725
    728726                if ( defined( 'DB_CHARSET' ) )
    729727                        $this->charset = DB_CHARSET;
     728
     729                if ( 'utf8' === $this->charset && $this->has_cap( 'utf8mb4' ) ) {
     730                        $this->charset = 'utf8mb4';
     731                }
     732
     733                if ( 'utf8mb4' === $this->charset && ( ! $this->collate || stripos( $this->collate, 'utf8_' ) === 0 ) ) {
     734                        $this->collate = 'utf8mb4_unicode_ci';
     735                }
    730736        }
    731737
    732738        /**
     
    14771483                        return false;
    14781484                } elseif ( $this->dbh ) {
    14791485                        $this->has_connected = true;
     1486
     1487                        $this->init_charset();
    14801488                        $this->set_charset( $this->dbh );
     1489
    14811490                        $this->ready = true;
    14821491                        $this->set_sql_mode();
    14831492                        $this->select( $this->dbname, $this->dbh );
     
    22492258         * Retrieves the character set for the given column.
    22502259         *
    22512260         * @since 4.2.0
    2252          * @access protected
     2261         * @access public
    22532262         *
    22542263         * @param string $table  Table name.
    22552264         * @param string $column Column name.
    22562265         * @return mixed Column character set as a string. False if the column has no
    22572266         *               character set. {@see WP_Error} object if there was an error.
    22582267         */
    2259         protected function get_col_charset( $table, $column ) {
     2268        public function get_col_charset( $table, $column ) {
    22602269                $tablekey = strtolower( $table );
    22612270                $columnkey = strtolower( $column );
    22622271
     
    23562365                        'gb2312'  => 'EUC-CN',
    23572366                        'ujis'    => 'EUC-JP',
    23582367                        'utf32'   => 'UTF-32',
    2359                         'utf8mb4' => 'UTF-8',
    23602368                );
    23612369
    23622370                $supported_charsets = array();
     
    23912399                                }
    23922400                        }
    23932401
    2394                         // utf8(mb3) can be handled by regex, which is a bunch faster than a DB lookup.
    2395                         if ( 'utf8' === $charset || 'utf8mb3' === $charset ) {
     2402                        // utf8 can be handled by regex, which is a bunch faster than a DB lookup.
     2403                        if ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset ) {
    23962404                                $regex = '/
    23972405                                        (
    23982406                                                (?: [\x00-\x7F]                  # single-byte sequences   0xxxxxxx
     
    24002408                                                |   \xE0[\xA0-\xBF][\x80-\xBF]   # triple-byte sequences   1110xxxx 10xxxxxx * 2
    24012409                                                |   [\xE1-\xEC][\x80-\xBF]{2}
    24022410                                                |   \xED[\x80-\x9F][\x80-\xBF]
    2403                                                 |   [\xEE-\xEF][\x80-\xBF]{2}
    2404                                                 ){1,50}                          # ...one or more times
     2411                                                |   [\xEE-\xEF][\x80-\xBF]{2}';
     2412
     2413                                if ( 'utf8mb4' === $charset) {
     2414                                        $regex .= '
     2415                                                |    \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences   11110xxx 10xxxxxx * 3
     2416                                                |    [\xF1-\xF3][\x80-\xBF]{3}
     2417                                                |    \xF4[\x80-\x8F][\x80-\xBF]{2}
     2418                                        ';
     2419                                }
     2420
     2421                                $regex .= '){1,50}                          # ...one or more times
    24052422                                        )
    24062423                                        | .                                  # anything else
    24072424                                        /x';
  • tests/phpunit/tests/db/charset.php

     
    130130        }
    131131
    132132        /**
    133          * @ ticket 21212
     133         * @ticket 21212
    134134         */
    135135        function test_process_fields_failure() {
    136136                global $wpdb;
    137                 $data = array( 'post_content' => "H€llo\xf0\x9f\x98\x88World¢" );
     137                // \xf0\xff\xff\xff is invalid in utf8 and utf8mb4
     138                $data = array( 'post_content' => "H€llo\xf0\xff\xff\xffWorld¢" );
    138139                $this->assertFalse( self::$_wpdb->process_fields( $wpdb->posts, $data, null ) );
    139140        }
    140141
     
    436437         */
    437438        function test_invalid_characters_in_query() {
    438439                global $wpdb;
    439                 $this->assertFalse( $wpdb->query( "INSERT INTO {$wpdb->posts} (post_content) VALUES ('foo\xf0\x9f\x98\x88bar')" ) );
     440                $this->assertFalse( $wpdb->query( "INSERT INTO {$wpdb->posts} (post_content) VALUES ('foo\xf0\xff\xff\xffbar')" ) );
    440441        }
    441442}