Changeset 32367 for branches/4.2/src/wp-includes/wp-db.php
- Timestamp:
- 05/06/2015 03:29:01 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/4.2/src/wp-includes/wp-db.php
r32307 r32367 1810 1810 */ 1811 1811 function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) { 1812 $this->insert_id = 0; 1813 1812 1814 if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) { 1813 1815 return false; … … 1830 1832 $sql = "$type INTO `$table` ($fields) VALUES ($formats)"; 1831 1833 1832 $this->insert_id = 0;1833 1834 $this->check_current_query = false; 1834 1835 return $this->query( $this->prepare( $sql, $values ) ); … … 2022 2023 // This checks %d/%f versus ! %s because it's sprintf() could take more. 2023 2024 $value['charset'] = false; 2024 } elseif ( $this->check_ascii( $value['value'] ) ) {2025 // If it's ASCII, then we don't need the charset. We can skip this field.2026 $value['charset'] = false;2027 2025 } else { 2028 2026 $value['charset'] = $this->get_col_charset( $table, $field ); … … 2030 2028 return false; 2031 2029 } 2032 2033 // This isn't ASCII. Don't have strip_invalid_text() re-check.2034 $value['ascii'] = false;2035 2030 } 2036 2031 … … 2063 2058 return false; 2064 2059 } 2065 }2066 2067 if ( false !== $value['length'] && mb_strlen( $value['value'] ) > $value['length'] ) {2068 return false;2069 2060 } 2070 2061 … … 2407 2398 /** 2408 2399 * Retrieve the maximum string length allowed in a given column. 2400 * The length may either be specified as a byte length or a character length. 2409 2401 * 2410 2402 * @since 4.2.1 … … 2413 2405 * @param string $table Table name. 2414 2406 * @param string $column Column name. 2415 * @return mixed Max column length as an int. False if the column has no 2416 * length. WP_Error object if there was an error. 2407 * @return mixed array( 'length' => (int), 'type' => 'byte' | 'char' ) 2408 * false if the column has no length (for example, numeric column) 2409 * WP_Error object if there was an error. 2417 2410 */ 2418 2411 public function get_col_length( $table, $column ) { … … 2447 2440 2448 2441 switch( $type ) { 2442 case 'char': 2443 case 'varchar': 2444 return array( 2445 'type' => 'char', 2446 'length' => (int) $length, 2447 ); 2448 break; 2449 2449 case 'binary': 2450 case 'char':2451 2450 case 'varbinary': 2452 case 'varchar': 2453 return $length; 2451 return array( 2452 'type' => 'byte', 2453 'length' => (int) $length, 2454 ); 2454 2455 break; 2455 2456 case 'tinyblob': 2456 2457 case 'tinytext': 2457 return 255; // 2^8 - 1 2458 return array( 2459 'type' => 'byte', 2460 'length' => 255, // 2^8 - 1 2461 ); 2458 2462 break; 2459 2463 case 'blob': 2460 2464 case 'text': 2461 return 65535; // 2^16 - 1 2465 return array( 2466 'type' => 'byte', 2467 'length' => 65535, // 2^16 - 1 2468 ); 2462 2469 break; 2463 2470 case 'mediumblob': 2464 2471 case 'mediumtext': 2465 return 16777215; // 2^24 - 1 2472 return array( 2473 'type' => 'byte', 2474 'length' => 16777215, // 2^24 - 1 2475 ); 2466 2476 break; 2467 2477 case 'longblob': 2468 2478 case 'longtext': 2469 return 4294967295; // 2^32 - 1 2479 return array( 2480 'type' => 'byte', 2481 'length' => 4294967295, // 2^32 - 1 2482 ); 2470 2483 break; 2471 2484 default: … … 2573 2586 */ 2574 2587 protected function strip_invalid_text( $data ) { 2575 // Some multibyte character sets that we can check in PHP.2576 $mb_charsets = array(2577 'ascii' => 'ASCII',2578 'big5' => 'BIG-5',2579 'eucjpms' => 'eucJP-win',2580 'gb2312' => 'EUC-CN',2581 'ujis' => 'EUC-JP',2582 'utf32' => 'UTF-32',2583 );2584 2585 $supported_charsets = array();2586 if ( function_exists( 'mb_list_encodings' ) ) {2587 $supported_charsets = mb_list_encodings();2588 }2589 2590 2588 $db_check_string = false; 2591 2589 … … 2593 2591 $charset = $value['charset']; 2594 2592 2595 // Column isn't a string, or is latin1, which will will happily store anything. 2596 if ( false === $charset || 'latin1' === $charset ) { 2593 if ( is_array( $value['length'] ) ) { 2594 $length = $value['length']['length']; 2595 } else { 2596 $length = false; 2597 } 2598 2599 // There's no charset to work with. 2600 if ( false === $charset ) { 2597 2601 continue; 2598 2602 } 2599 2603 2604 // Column isn't a string. 2600 2605 if ( ! is_string( $value['value'] ) ) { 2601 2606 continue; 2602 2607 } 2603 2608 2604 // ASCII is always OK. 2605 if ( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) ) { 2606 continue; 2607 } 2608 2609 // Convert the text locally. 2610 if ( $supported_charsets ) { 2611 if ( isset( $mb_charsets[ $charset ] ) && in_array( $mb_charsets[ $charset ], $supported_charsets ) ) { 2612 $value['value'] = mb_convert_encoding( $value['value'], $mb_charsets[ $charset ], $mb_charsets[ $charset ] ); 2609 $truncate_by_byte_length = 'byte' === $value['length']['type']; 2610 2611 $needs_validation = true; 2612 if ( 2613 // latin1 can store any byte sequence 2614 'latin1' === $charset 2615 || 2616 // ASCII is always OK. 2617 ( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) ) 2618 ) { 2619 $truncate_by_byte_length = true; 2620 $needs_validation = false; 2621 } 2622 2623 if ( $truncate_by_byte_length ) { 2624 mbstring_binary_safe_encoding(); 2625 if ( false !== $length && strlen( $value['value'] ) > $length ) { 2626 $value['value'] = substr( $value['value'], 0, $length ); 2627 } 2628 reset_mbstring_encoding(); 2629 2630 if ( ! $needs_validation ) { 2613 2631 continue; 2614 2632 } … … 2616 2634 2617 2635 // utf8 can be handled by regex, which is a bunch faster than a DB lookup. 2618 if ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset) {2636 if ( ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset ) && function_exists( 'mb_strlen' ) ) { 2619 2637 $regex = '/ 2620 2638 ( … … 2626 2644 | [\xEE-\xEF][\x80-\xBF]{2}'; 2627 2645 2628 if ( 'utf8mb4' === $charset ) {2646 if ( 'utf8mb4' === $charset ) { 2629 2647 $regex .= ' 2630 2648 | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3 … … 2639 2657 /x'; 2640 2658 $value['value'] = preg_replace( $regex, '$1', $value['value'] ); 2659 2660 2661 if ( false !== $length && mb_strlen( $value['value'], 'UTF-8' ) > $length ) { 2662 $value['value'] = mb_substr( $value['value'], 0, $length, 'UTF-8' ); 2663 } 2641 2664 continue; 2642 2665 } … … 2655 2678 } 2656 2679 2657 // Split the CONVERT() calls by charset, so we can make sure the connection is right 2658 $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( %s USING {$value['charset']} )", $value['value'] ); 2680 // We're going to need to truncate by characters or bytes, depending on the length value we have. 2681 if ( 'byte' === $value['length']['type'] ) { 2682 // Split the CONVERT() calls by charset, so we can make sure the connection is right 2683 $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING binary ), %d ) USING {$value['charset']} )", $value['value'], $value['length']['length'] ); 2684 } else { 2685 $queries[ $value['charset'] ][ $col ] = $this->prepare( "LEFT( CONVERT( %s USING {$value['charset']} ), %d )", $value['value'], $value['length']['length'] ); 2686 } 2687 2659 2688 unset( $data[ $col ]['db'] ); 2660 2689 } … … 2675 2704 $this->check_current_query = false; 2676 2705 2677 $row = $this->get_row( "SELECT " . implode( ', ', $query ), ARRAY_N ); 2706 $sql = array(); 2707 foreach ( $query as $column => $column_query ) { 2708 $sql[] = $column_query . " AS x_$column"; 2709 } 2710 2711 $row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A ); 2678 2712 if ( ! $row ) { 2679 2713 $this->set_charset( $this->dbh, $connection_charset ); … … 2681 2715 } 2682 2716 2683 $cols = array_keys( $query ); 2684 $col_count = count( $cols ); 2685 for ( $ii = 0; $ii < $col_count; $ii++ ) { 2686 $data[ $cols[ $ii ] ]['value'] = $row[ $ii ]; 2717 foreach ( array_keys( $query ) as $column ) { 2718 $data[ $column ]['value'] = $row["x_$column"]; 2687 2719 } 2688 2720 } … … 2726 2758 'charset' => $charset, 2727 2759 'ascii' => false, 2760 'length' => false, 2728 2761 ); 2729 2762 … … 2748 2781 */ 2749 2782 public function strip_invalid_text_for_column( $table, $column, $value ) { 2750 if ( ! is_string( $value ) || $this->check_ascii( $value )) {2783 if ( ! is_string( $value ) ) { 2751 2784 return $value; 2752 2785 } … … 2765 2798 'value' => $value, 2766 2799 'charset' => $charset, 2767 ' ascii' => false,2800 'length' => $this->get_col_length( $table, $column ), 2768 2801 ) 2769 2802 );
Note: See TracChangeset
for help on using the changeset viewer.