Changeset 32388 for branches/4.0/src/wp-includes/wp-db.php
- Timestamp:
- 05/06/2015 07:08:42 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/4.0/src/wp-includes/wp-db.php
r32313 r32388 1788 1788 */ 1789 1789 function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) { 1790 $this->insert_id = 0; 1791 1790 1792 if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) { 1791 1793 return false; … … 1808 1810 $sql = "$type INTO `$table` ($fields) VALUES ($formats)"; 1809 1811 1810 $this->insert_id = 0;1811 1812 $this->check_current_query = false; 1812 1813 return $this->query( $this->prepare( $sql, $values ) ); … … 2004 2005 // This checks %d/%f versus ! %s because it's sprintf() could take more. 2005 2006 $value['charset'] = false; 2006 } elseif ( $this->check_ascii( $value['value'] ) ) {2007 // If it's ASCII, then we don't need the charset. We can skip this field.2008 $value['charset'] = false;2009 2007 } else { 2010 2008 $value['charset'] = $this->get_col_charset( $table, $field ); … … 2012 2010 return false; 2013 2011 } 2014 2015 // This isn't ASCII. Don't have strip_invalid_text() re-check.2016 $value['ascii'] = false;2017 2012 } 2018 2013 … … 2045 2040 return false; 2046 2041 } 2047 }2048 2049 if ( false !== $value['length'] && strlen( $value['value'] ) > $value['length'] ) {2050 return false;2051 2042 } 2052 2043 … … 2380 2371 /** 2381 2372 * Retrieve the maximum string length allowed in a given column. 2373 * The length may either be specified as a byte length or a character length. 2382 2374 * 2383 2375 * @since 4.2.1 … … 2386 2378 * @param string $table Table name. 2387 2379 * @param string $column Column name. 2388 * @return mixed Max column length as an int. False if the column has no 2389 * length. WP_Error object if there was an error. 2380 * @return mixed array( 'length' => (int), 'type' => 'byte' | 'char' ) 2381 * false if the column has no length (for example, numeric column) 2382 * WP_Error object if there was an error. 2390 2383 */ 2391 2384 public function get_col_length( $table, $column ) { … … 2420 2413 2421 2414 switch( $type ) { 2415 case 'char': 2416 case 'varchar': 2417 return array( 2418 'type' => 'char', 2419 'length' => (int) $length, 2420 ); 2421 break; 2422 2422 case 'binary': 2423 case 'char':2424 2423 case 'varbinary': 2425 case 'varchar': 2426 return $length; 2424 return array( 2425 'type' => 'byte', 2426 'length' => (int) $length, 2427 ); 2427 2428 break; 2428 2429 case 'tinyblob': 2429 2430 case 'tinytext': 2430 return 255; // 2^8 - 1 2431 return array( 2432 'type' => 'byte', 2433 'length' => 255, // 2^8 - 1 2434 ); 2431 2435 break; 2432 2436 case 'blob': 2433 2437 case 'text': 2434 return 65535; // 2^16 - 1 2438 return array( 2439 'type' => 'byte', 2440 'length' => 65535, // 2^16 - 1 2441 ); 2435 2442 break; 2436 2443 case 'mediumblob': 2437 2444 case 'mediumtext': 2438 return 16777215; // 2^24 - 1 2445 return array( 2446 'type' => 'byte', 2447 'length' => 16777215, // 2^24 - 1 2448 ); 2439 2449 break; 2440 2450 case 'longblob': 2441 2451 case 'longtext': 2442 return 4294967295; // 2^32 - 1 2452 return array( 2453 'type' => 'byte', 2454 'length' => 4294967295, // 2^32 - 1 2455 ); 2443 2456 break; 2444 2457 default: … … 2547 2560 // If any of the columns don't have one of these collations, it needs more sanity checking. 2548 2561 protected function strip_invalid_text( $data ) { 2549 // Some multibyte character sets that we can check in PHP.2550 $mb_charsets = array(2551 'ascii' => 'ASCII',2552 'big5' => 'BIG-5',2553 'eucjpms' => 'eucJP-win',2554 'gb2312' => 'EUC-CN',2555 'ujis' => 'EUC-JP',2556 'utf32' => 'UTF-32',2557 );2558 2559 $supported_charsets = array();2560 if ( function_exists( 'mb_list_encodings' ) ) {2561 $supported_charsets = mb_list_encodings();2562 }2563 2564 2562 $db_check_string = false; 2565 2563 … … 2567 2565 $charset = $value['charset']; 2568 2566 2569 // Column isn't a string, or is latin1, which will will happily store anything. 2570 if ( false === $charset || 'latin1' === $charset ) { 2567 if ( is_array( $value['length'] ) ) { 2568 $length = $value['length']['length']; 2569 } else { 2570 $length = false; 2571 } 2572 2573 // There's no charset to work with. 2574 if ( false === $charset ) { 2571 2575 continue; 2572 2576 } 2573 2577 2578 // Column isn't a string. 2574 2579 if ( ! is_string( $value['value'] ) ) { 2575 2580 continue; 2576 2581 } 2577 2582 2578 // ASCII is always OK. 2579 if ( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) ) { 2580 continue; 2581 } 2582 2583 // Convert the text locally. 2584 if ( $supported_charsets ) { 2585 if ( isset( $mb_charsets[ $charset ] ) && in_array( $mb_charsets[ $charset ], $supported_charsets ) ) { 2586 $value['value'] = mb_convert_encoding( $value['value'], $mb_charsets[ $charset ], $mb_charsets[ $charset ] ); 2583 $truncate_by_byte_length = 'byte' === $value['length']['type']; 2584 2585 $needs_validation = true; 2586 if ( 2587 // latin1 can store any byte sequence 2588 'latin1' === $charset 2589 || 2590 // ASCII is always OK. 2591 ( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) ) 2592 ) { 2593 $truncate_by_byte_length = true; 2594 $needs_validation = false; 2595 } 2596 2597 if ( $truncate_by_byte_length ) { 2598 mbstring_binary_safe_encoding(); 2599 if ( false !== $length && strlen( $value['value'] ) > $length ) { 2600 $value['value'] = substr( $value['value'], 0, $length ); 2601 } 2602 reset_mbstring_encoding(); 2603 2604 if ( ! $needs_validation ) { 2587 2605 continue; 2588 2606 } … … 2590 2608 2591 2609 // utf8 can be handled by regex, which is a bunch faster than a DB lookup. 2592 if ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset) {2610 if ( ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset ) && function_exists( 'mb_strlen' ) ) { 2593 2611 $regex = '/ 2594 2612 ( … … 2600 2618 | [\xEE-\xEF][\x80-\xBF]{2}'; 2601 2619 2602 if ( 'utf8mb4' === $charset ) {2620 if ( 'utf8mb4' === $charset ) { 2603 2621 $regex .= ' 2604 2622 | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3 … … 2613 2631 /x'; 2614 2632 $value['value'] = preg_replace( $regex, '$1', $value['value'] ); 2633 2634 2635 if ( false !== $length && mb_strlen( $value['value'], 'UTF-8' ) > $length ) { 2636 $value['value'] = mb_substr( $value['value'], 0, $length, 'UTF-8' ); 2637 } 2615 2638 continue; 2616 2639 } … … 2629 2652 } 2630 2653 2631 // Split the CONVERT() calls by charset, so we can make sure the connection is right 2632 $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( %s USING {$value['charset']} )", $value['value'] ); 2654 // We're going to need to truncate by characters or bytes, depending on the length value we have. 2655 if ( 'byte' === $value['length']['type'] ) { 2656 // Split the CONVERT() calls by charset, so we can make sure the connection is right 2657 $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING binary ), %d ) USING {$value['charset']} )", $value['value'], $value['length']['length'] ); 2658 } else { 2659 $queries[ $value['charset'] ][ $col ] = $this->prepare( "LEFT( CONVERT( %s USING {$value['charset']} ), %d )", $value['value'], $value['length']['length'] ); 2660 } 2661 2633 2662 unset( $data[ $col ]['db'] ); 2634 2663 } … … 2649 2678 $this->check_current_query = false; 2650 2679 2651 $row = $this->get_row( "SELECT " . implode( ', ', $query ), ARRAY_N ); 2680 $sql = array(); 2681 foreach ( $query as $column => $column_query ) { 2682 $sql[] = $column_query . " AS x_$column"; 2683 } 2684 2685 $row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A ); 2652 2686 if ( ! $row ) { 2653 2687 $this->set_charset( $this->dbh, $connection_charset ); … … 2655 2689 } 2656 2690 2657 $cols = array_keys( $query ); 2658 $col_count = count( $cols ); 2659 for ( $ii = 0; $ii < $col_count; $ii++ ) { 2660 $data[ $cols[ $ii ] ]['value'] = $row[ $ii ]; 2691 foreach ( array_keys( $query ) as $column ) { 2692 $data[ $column ]['value'] = $row["x_$column"]; 2661 2693 } 2662 2694 } … … 2700 2732 'charset' => $charset, 2701 2733 'ascii' => false, 2734 'length' => false, 2702 2735 ); 2703 2736 … … 2722 2755 */ 2723 2756 public function strip_invalid_text_for_column( $table, $column, $value ) { 2724 if ( ! is_string( $value ) || $this->check_ascii( $value )) {2757 if ( ! is_string( $value ) ) { 2725 2758 return $value; 2726 2759 } … … 2739 2772 'value' => $value, 2740 2773 'charset' => $charset, 2741 ' ascii' => false,2774 'length' => $this->get_col_length( $table, $column ), 2742 2775 ) 2743 2776 );
Note: See TracChangeset
for help on using the changeset viewer.