Changeset 32391 for branches/3.7/src/wp-includes/wp-db.php
- Timestamp:
- 05/06/2015 07:16:41 PM (11 years ago)
- File:
-
- 1 edited
-
branches/3.7/src/wp-includes/wp-db.php (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/3.7/src/wp-includes/wp-db.php
r32318 r32391 1372 1372 */ 1373 1373 function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) { 1374 $this->insert_id = 0; 1375 1374 1376 if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) { 1375 1377 return false; … … 1392 1394 $sql = "$type INTO `$table` ($fields) VALUES ($formats)"; 1393 1395 1394 $this->insert_id = 0;1395 1396 $this->check_current_query = false; 1396 1397 return $this->query( $this->prepare( $sql, $values ) ); … … 1589 1590 // This checks %d/%f versus ! %s because it's sprintf() could take more. 1590 1591 $value['charset'] = false; 1591 } elseif ( $this->check_ascii( $value['value'] ) ) {1592 // If it's ASCII, then we don't need the charset. We can skip this field.1593 $value['charset'] = false;1594 1592 } else { 1595 1593 $value['charset'] = $this->get_col_charset( $table, $field ); … … 1597 1595 return false; 1598 1596 } 1599 1600 // This isn't ASCII. Don't have strip_invalid_text() re-check.1601 $value['ascii'] = false;1602 1597 } 1603 1598 … … 1630 1625 return false; 1631 1626 } 1632 }1633 1634 if ( false !== $value['length'] && strlen( $value['value'] ) > $value['length'] ) {1635 return false;1636 1627 } 1637 1628 … … 1959 1950 /** 1960 1951 * Retrieve the maximum string length allowed in a given column. 1952 * The length may either be specified as a byte length or a character length. 1961 1953 * 1962 1954 * @since 4.2.1 … … 1965 1957 * @param string $table Table name. 1966 1958 * @param string $column Column name. 1967 * @return mixed Max column length as an int. False if the column has no 1968 * length. WP_Error object if there was an error. 1959 * @return mixed array( 'length' => (int), 'type' => 'byte' | 'char' ) 1960 * false if the column has no length (for example, numeric column) 1961 * WP_Error object if there was an error. 1969 1962 */ 1970 1963 public function get_col_length( $table, $column ) { … … 1999 1992 2000 1993 switch( $type ) { 1994 case 'char': 1995 case 'varchar': 1996 return array( 1997 'type' => 'char', 1998 'length' => (int) $length, 1999 ); 2000 break; 2001 2001 case 'binary': 2002 case 'char':2003 2002 case 'varbinary': 2004 case 'varchar': 2005 return $length; 2003 return array( 2004 'type' => 'byte', 2005 'length' => (int) $length, 2006 ); 2006 2007 break; 2007 2008 case 'tinyblob': 2008 2009 case 'tinytext': 2009 return 255; // 2^8 - 1 2010 return array( 2011 'type' => 'byte', 2012 'length' => 255, // 2^8 - 1 2013 ); 2010 2014 break; 2011 2015 case 'blob': 2012 2016 case 'text': 2013 return 65535; // 2^16 - 1 2017 return array( 2018 'type' => 'byte', 2019 'length' => 65535, // 2^16 - 1 2020 ); 2014 2021 break; 2015 2022 case 'mediumblob': 2016 2023 case 'mediumtext': 2017 return 16777215; // 2^24 - 1 2024 return array( 2025 'type' => 'byte', 2026 'length' => 16777215, // 2^24 - 1 2027 ); 2018 2028 break; 2019 2029 case 'longblob': 2020 2030 case 'longtext': 2021 return 4294967295; // 2^32 - 1 2031 return array( 2032 'type' => 'byte', 2033 'length' => 4294967295, // 2^32 - 1 2034 ); 2022 2035 break; 2023 2036 default: … … 2126 2139 // If any of the columns don't have one of these collations, it needs more sanity checking. 2127 2140 protected function strip_invalid_text( $data ) { 2128 // Some multibyte character sets that we can check in PHP.2129 $mb_charsets = array(2130 'ascii' => 'ASCII',2131 'big5' => 'BIG-5',2132 'eucjpms' => 'eucJP-win',2133 'gb2312' => 'EUC-CN',2134 'ujis' => 'EUC-JP',2135 'utf32' => 'UTF-32',2136 );2137 2138 $supported_charsets = array();2139 if ( function_exists( 'mb_list_encodings' ) ) {2140 $supported_charsets = mb_list_encodings();2141 }2142 2143 2141 $db_check_string = false; 2144 2142 … … 2146 2144 $charset = $value['charset']; 2147 2145 2148 // Column isn't a string, or is latin1, which will will happily store anything. 2149 if ( false === $charset || 'latin1' === $charset ) { 2146 if ( is_array( $value['length'] ) ) { 2147 $length = $value['length']['length']; 2148 } else { 2149 $length = false; 2150 } 2151 2152 // There's no charset to work with. 2153 if ( false === $charset ) { 2150 2154 continue; 2151 2155 } 2152 2156 2157 // Column isn't a string. 2153 2158 if ( ! is_string( $value['value'] ) ) { 2154 2159 continue; 2155 2160 } 2156 2161 2157 // ASCII is always OK. 2158 if ( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) ) { 2159 continue; 2160 } 2161 2162 // Convert the text locally. 2163 if ( $supported_charsets ) { 2164 if ( isset( $mb_charsets[ $charset ] ) && in_array( $mb_charsets[ $charset ], $supported_charsets ) ) { 2165 $value['value'] = mb_convert_encoding( $value['value'], $mb_charsets[ $charset ], $mb_charsets[ $charset ] ); 2162 $truncate_by_byte_length = 'byte' === $value['length']['type']; 2163 2164 $needs_validation = true; 2165 if ( 2166 // latin1 can store any byte sequence 2167 'latin1' === $charset 2168 || 2169 // ASCII is always OK. 2170 ( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) ) 2171 ) { 2172 $truncate_by_byte_length = true; 2173 $needs_validation = false; 2174 } 2175 2176 if ( $truncate_by_byte_length ) { 2177 mbstring_binary_safe_encoding(); 2178 if ( false !== $length && strlen( $value['value'] ) > $length ) { 2179 $value['value'] = substr( $value['value'], 0, $length ); 2180 } 2181 reset_mbstring_encoding(); 2182 2183 if ( ! $needs_validation ) { 2166 2184 continue; 2167 2185 } … … 2169 2187 2170 2188 // utf8 can be handled by regex, which is a bunch faster than a DB lookup. 2171 if ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset) {2189 if ( ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset ) && function_exists( 'mb_strlen' ) ) { 2172 2190 $regex = '/ 2173 2191 ( … … 2179 2197 | [\xEE-\xEF][\x80-\xBF]{2}'; 2180 2198 2181 if ( 'utf8mb4' === $charset ) {2199 if ( 'utf8mb4' === $charset ) { 2182 2200 $regex .= ' 2183 2201 | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3 … … 2192 2210 /x'; 2193 2211 $value['value'] = preg_replace( $regex, '$1', $value['value'] ); 2212 2213 2214 if ( false !== $length && mb_strlen( $value['value'], 'UTF-8' ) > $length ) { 2215 $value['value'] = mb_substr( $value['value'], 0, $length, 'UTF-8' ); 2216 } 2194 2217 continue; 2195 2218 } … … 2208 2231 } 2209 2232 2210 // Split the CONVERT() calls by charset, so we can make sure the connection is right 2211 $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( %s USING {$value['charset']} )", $value['value'] ); 2233 // We're going to need to truncate by characters or bytes, depending on the length value we have. 2234 if ( 'byte' === $value['length']['type'] ) { 2235 // Split the CONVERT() calls by charset, so we can make sure the connection is right 2236 $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING binary ), %d ) USING {$value['charset']} )", $value['value'], $value['length']['length'] ); 2237 } else { 2238 $queries[ $value['charset'] ][ $col ] = $this->prepare( "LEFT( CONVERT( %s USING {$value['charset']} ), %d )", $value['value'], $value['length']['length'] ); 2239 } 2240 2212 2241 unset( $data[ $col ]['db'] ); 2213 2242 } … … 2228 2257 $this->check_current_query = false; 2229 2258 2230 $row = $this->get_row( "SELECT " . implode( ', ', $query ), ARRAY_N ); 2259 $sql = array(); 2260 foreach ( $query as $column => $column_query ) { 2261 $sql[] = $column_query . " AS x_$column"; 2262 } 2263 2264 $row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A ); 2231 2265 if ( ! $row ) { 2232 2266 $this->set_charset( $this->dbh, $connection_charset ); … … 2234 2268 } 2235 2269 2236 $cols = array_keys( $query ); 2237 $col_count = count( $cols ); 2238 for ( $ii = 0; $ii < $col_count; $ii++ ) { 2239 $data[ $cols[ $ii ] ]['value'] = $row[ $ii ]; 2270 foreach ( array_keys( $query ) as $column ) { 2271 $data[ $column ]['value'] = $row["x_$column"]; 2240 2272 } 2241 2273 } … … 2279 2311 'charset' => $charset, 2280 2312 'ascii' => false, 2313 'length' => false, 2281 2314 ); 2282 2315 … … 2301 2334 */ 2302 2335 public function strip_invalid_text_for_column( $table, $column, $value ) { 2303 if ( ! is_string( $value ) || $this->check_ascii( $value )) {2336 if ( ! is_string( $value ) ) { 2304 2337 return $value; 2305 2338 } … … 2318 2351 'value' => $value, 2319 2352 'charset' => $charset, 2320 ' ascii' => false,2353 'length' => $this->get_col_length( $table, $column ), 2321 2354 ) 2322 2355 );
Note: See TracChangeset
for help on using the changeset viewer.