Changeset 32389 for branches/3.9/src/wp-includes/wp-db.php
- Timestamp:
- 05/06/2015 07:11:47 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.9/src/wp-includes/wp-db.php
r32316 r32389 1752 1752 */ 1753 1753 function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) { 1754 $this->insert_id = 0; 1755 1754 1756 if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) { 1755 1757 return false; … … 1772 1774 $sql = "$type INTO `$table` ($fields) VALUES ($formats)"; 1773 1775 1774 $this->insert_id = 0;1775 1776 $this->check_current_query = false; 1776 1777 return $this->query( $this->prepare( $sql, $values ) ); … … 1969 1970 // This checks %d/%f versus ! %s because it's sprintf() could take more. 1970 1971 $value['charset'] = false; 1971 } elseif ( $this->check_ascii( $value['value'] ) ) {1972 // If it's ASCII, then we don't need the charset. We can skip this field.1973 $value['charset'] = false;1974 1972 } else { 1975 1973 $value['charset'] = $this->get_col_charset( $table, $field ); … … 1977 1975 return false; 1978 1976 } 1979 1980 // This isn't ASCII. Don't have strip_invalid_text() re-check.1981 $value['ascii'] = false;1982 1977 } 1983 1978 … … 2010 2005 return false; 2011 2006 } 2012 }2013 2014 if ( false !== $value['length'] && strlen( $value['value'] ) > $value['length'] ) {2015 return false;2016 2007 } 2017 2008 … … 2344 2335 /** 2345 2336 * Retrieve the maximum string length allowed in a given column. 2337 * The length may either be specified as a byte length or a character length. 2346 2338 * 2347 2339 * @since 4.2.1 … … 2350 2342 * @param string $table Table name. 2351 2343 * @param string $column Column name. 2352 * @return mixed Max column length as an int. False if the column has no 2353 * length. WP_Error object if there was an error. 2344 * @return mixed array( 'length' => (int), 'type' => 'byte' | 'char' ) 2345 * false if the column has no length (for example, numeric column) 2346 * WP_Error object if there was an error. 2354 2347 */ 2355 2348 public function get_col_length( $table, $column ) { … … 2384 2377 2385 2378 switch( $type ) { 2379 case 'char': 2380 case 'varchar': 2381 return array( 2382 'type' => 'char', 2383 'length' => (int) $length, 2384 ); 2385 break; 2386 2386 case 'binary': 2387 case 'char':2388 2387 case 'varbinary': 2389 case 'varchar': 2390 return $length; 2388 return array( 2389 'type' => 'byte', 2390 'length' => (int) $length, 2391 ); 2391 2392 break; 2392 2393 case 'tinyblob': 2393 2394 case 'tinytext': 2394 return 255; // 2^8 - 1 2395 return array( 2396 'type' => 'byte', 2397 'length' => 255, // 2^8 - 1 2398 ); 2395 2399 break; 2396 2400 case 'blob': 2397 2401 case 'text': 2398 return 65535; // 2^16 - 1 2402 return array( 2403 'type' => 'byte', 2404 'length' => 65535, // 2^16 - 1 2405 ); 2399 2406 break; 2400 2407 case 'mediumblob': 2401 2408 case 'mediumtext': 2402 return 16777215; // 2^24 - 1 2409 return array( 2410 'type' => 'byte', 2411 'length' => 16777215, // 2^24 - 1 2412 ); 2403 2413 break; 2404 2414 case 'longblob': 2405 2415 case 'longtext': 2406 return 4294967295; // 2^32 - 1 2416 return array( 2417 'type' => 'byte', 2418 'length' => 4294967295, // 2^32 - 1 2419 ); 2407 2420 break; 2408 2421 default: … … 2511 2524 // If any of the columns don't have one of these collations, it needs more sanity checking. 2512 2525 protected function strip_invalid_text( $data ) { 2513 // Some multibyte character sets that we can check in PHP.2514 $mb_charsets = array(2515 'ascii' => 'ASCII',2516 'big5' => 'BIG-5',2517 'eucjpms' => 'eucJP-win',2518 'gb2312' => 'EUC-CN',2519 'ujis' => 'EUC-JP',2520 'utf32' => 'UTF-32',2521 );2522 2523 $supported_charsets = array();2524 if ( function_exists( 'mb_list_encodings' ) ) {2525 $supported_charsets = mb_list_encodings();2526 }2527 2528 2526 $db_check_string = false; 2529 2527 … … 2531 2529 $charset = $value['charset']; 2532 2530 2533 // Column isn't a string, or is latin1, which will will happily store anything. 2534 if ( false === $charset || 'latin1' === $charset ) { 2531 if ( is_array( $value['length'] ) ) { 2532 $length = $value['length']['length']; 2533 } else { 2534 $length = false; 2535 } 2536 2537 // There's no charset to work with. 2538 if ( false === $charset ) { 2535 2539 continue; 2536 2540 } 2537 2541 2542 // Column isn't a string. 2538 2543 if ( ! is_string( $value['value'] ) ) { 2539 2544 continue; 2540 2545 } 2541 2546 2542 // ASCII is always OK. 2543 if ( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) ) { 2544 continue; 2545 } 2546 2547 // Convert the text locally. 2548 if ( $supported_charsets ) { 2549 if ( isset( $mb_charsets[ $charset ] ) && in_array( $mb_charsets[ $charset ], $supported_charsets ) ) { 2550 $value['value'] = mb_convert_encoding( $value['value'], $mb_charsets[ $charset ], $mb_charsets[ $charset ] ); 2547 $truncate_by_byte_length = 'byte' === $value['length']['type']; 2548 2549 $needs_validation = true; 2550 if ( 2551 // latin1 can store any byte sequence 2552 'latin1' === $charset 2553 || 2554 // ASCII is always OK. 2555 ( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) ) 2556 ) { 2557 $truncate_by_byte_length = true; 2558 $needs_validation = false; 2559 } 2560 2561 if ( $truncate_by_byte_length ) { 2562 mbstring_binary_safe_encoding(); 2563 if ( false !== $length && strlen( $value['value'] ) > $length ) { 2564 $value['value'] = substr( $value['value'], 0, $length ); 2565 } 2566 reset_mbstring_encoding(); 2567 2568 if ( ! $needs_validation ) { 2551 2569 continue; 2552 2570 } … … 2554 2572 2555 2573 // utf8 can be handled by regex, which is a bunch faster than a DB lookup. 2556 if ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset) {2574 if ( ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset ) && function_exists( 'mb_strlen' ) ) { 2557 2575 $regex = '/ 2558 2576 ( … … 2564 2582 | [\xEE-\xEF][\x80-\xBF]{2}'; 2565 2583 2566 if ( 'utf8mb4' === $charset ) {2584 if ( 'utf8mb4' === $charset ) { 2567 2585 $regex .= ' 2568 2586 | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3 … … 2577 2595 /x'; 2578 2596 $value['value'] = preg_replace( $regex, '$1', $value['value'] ); 2597 2598 2599 if ( false !== $length && mb_strlen( $value['value'], 'UTF-8' ) > $length ) { 2600 $value['value'] = mb_substr( $value['value'], 0, $length, 'UTF-8' ); 2601 } 2579 2602 continue; 2580 2603 } … … 2593 2616 } 2594 2617 2595 // Split the CONVERT() calls by charset, so we can make sure the connection is right 2596 $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( %s USING {$value['charset']} )", $value['value'] ); 2618 // We're going to need to truncate by characters or bytes, depending on the length value we have. 2619 if ( 'byte' === $value['length']['type'] ) { 2620 // Split the CONVERT() calls by charset, so we can make sure the connection is right 2621 $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING binary ), %d ) USING {$value['charset']} )", $value['value'], $value['length']['length'] ); 2622 } else { 2623 $queries[ $value['charset'] ][ $col ] = $this->prepare( "LEFT( CONVERT( %s USING {$value['charset']} ), %d )", $value['value'], $value['length']['length'] ); 2624 } 2625 2597 2626 unset( $data[ $col ]['db'] ); 2598 2627 } … … 2613 2642 $this->check_current_query = false; 2614 2643 2615 $row = $this->get_row( "SELECT " . implode( ', ', $query ), ARRAY_N ); 2644 $sql = array(); 2645 foreach ( $query as $column => $column_query ) { 2646 $sql[] = $column_query . " AS x_$column"; 2647 } 2648 2649 $row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A ); 2616 2650 if ( ! $row ) { 2617 2651 $this->set_charset( $this->dbh, $connection_charset ); … … 2619 2653 } 2620 2654 2621 $cols = array_keys( $query ); 2622 $col_count = count( $cols ); 2623 for ( $ii = 0; $ii < $col_count; $ii++ ) { 2624 $data[ $cols[ $ii ] ]['value'] = $row[ $ii ]; 2655 foreach ( array_keys( $query ) as $column ) { 2656 $data[ $column ]['value'] = $row["x_$column"]; 2625 2657 } 2626 2658 } … … 2664 2696 'charset' => $charset, 2665 2697 'ascii' => false, 2698 'length' => false, 2666 2699 ); 2667 2700 … … 2686 2719 */ 2687 2720 public function strip_invalid_text_for_column( $table, $column, $value ) { 2688 if ( ! is_string( $value ) || $this->check_ascii( $value )) {2721 if ( ! is_string( $value ) ) { 2689 2722 return $value; 2690 2723 } … … 2703 2736 'value' => $value, 2704 2737 'charset' => $charset, 2705 ' ascii' => false,2738 'length' => $this->get_col_length( $table, $column ), 2706 2739 ) 2707 2740 );
Note: See TracChangeset
for help on using the changeset viewer.