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