WPDB: Sanity check that any strings being stored in the DB are not too long to store correctly.
Merge [32299] to the 4.1 and 4.2 branches. Built from https://develop.svn.wordpress.org/@32307 git-svn-id: http://core.svn.wordpress.org/branches/4.2@32278 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
f0a9d2e5a1
commit
5c2b420b29
|
@ -1946,11 +1946,20 @@ class wpdb {
|
||||||
*/
|
*/
|
||||||
protected function process_fields( $table, $data, $format ) {
|
protected function process_fields( $table, $data, $format ) {
|
||||||
$data = $this->process_field_formats( $data, $format );
|
$data = $this->process_field_formats( $data, $format );
|
||||||
|
if ( false === $data ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$data = $this->process_field_charsets( $data, $table );
|
$data = $this->process_field_charsets( $data, $table );
|
||||||
if ( false === $data ) {
|
if ( false === $data ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$data = $this->process_field_lengths( $data, $table );
|
||||||
|
if ( false === $data ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$converted_data = $this->strip_invalid_text( $data );
|
$converted_data = $this->strip_invalid_text( $data );
|
||||||
|
|
||||||
if ( $data !== $converted_data ) {
|
if ( $data !== $converted_data ) {
|
||||||
|
@ -2031,6 +2040,40 @@ class wpdb {
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For string fields, record the maximum string length that field can safely save.
|
||||||
|
*
|
||||||
|
* @since 4.2.1
|
||||||
|
* @access protected
|
||||||
|
*
|
||||||
|
* @param array $data As it comes from the wpdb::process_field_charsets() method.
|
||||||
|
* @param string $table Table name.
|
||||||
|
* @return array|False The same array as $data with additional 'length' keys, or false if
|
||||||
|
* any of the values were too long for their corresponding field.
|
||||||
|
*/
|
||||||
|
protected function process_field_lengths( $data, $table ) {
|
||||||
|
foreach ( $data as $field => $value ) {
|
||||||
|
if ( '%d' === $value['format'] || '%f' === $value['format'] ) {
|
||||||
|
// We can skip this field if we know it isn't a string.
|
||||||
|
// This checks %d/%f versus ! %s because it's sprintf() could take more.
|
||||||
|
$value['length'] = false;
|
||||||
|
} else {
|
||||||
|
$value['length'] = $this->get_col_length( $table, $field );
|
||||||
|
if ( is_wp_error( $value['length'] ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( false !== $value['length'] && mb_strlen( $value['value'] ) > $value['length'] ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data[ $field ] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve one variable from the database.
|
* Retrieve one variable from the database.
|
||||||
*
|
*
|
||||||
|
@ -2361,6 +2404,77 @@ class wpdb {
|
||||||
return $charset;
|
return $charset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the maximum string length allowed in a given column.
|
||||||
|
*
|
||||||
|
* @since 4.2.1
|
||||||
|
* @access public
|
||||||
|
*
|
||||||
|
* @param string $table Table name.
|
||||||
|
* @param string $column Column name.
|
||||||
|
* @return mixed Max column length as an int. False if the column has no
|
||||||
|
* length. WP_Error object if there was an error.
|
||||||
|
*/
|
||||||
|
public function get_col_length( $table, $column ) {
|
||||||
|
$tablekey = strtolower( $table );
|
||||||
|
$columnkey = strtolower( $column );
|
||||||
|
|
||||||
|
// Skip this entirely if this isn't a MySQL database.
|
||||||
|
if ( false === $this->is_mysql ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( empty( $this->col_meta[ $tablekey ] ) ) {
|
||||||
|
// This primes column information for us.
|
||||||
|
$table_charset = $this->get_table_charset( $table );
|
||||||
|
if ( is_wp_error( $table_charset ) ) {
|
||||||
|
return $table_charset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( empty( $this->col_meta[ $tablekey ][ $columnkey ] ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$typeinfo = explode( '(', $this->col_meta[ $tablekey ][ $columnkey ]->Type );
|
||||||
|
|
||||||
|
$type = strtolower( $typeinfo[0] );
|
||||||
|
if ( ! empty( $typeinfo[1] ) ) {
|
||||||
|
$length = trim( $typeinfo[1], ')' );
|
||||||
|
} else {
|
||||||
|
$length = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( $type ) {
|
||||||
|
case 'binary':
|
||||||
|
case 'char':
|
||||||
|
case 'varbinary':
|
||||||
|
case 'varchar':
|
||||||
|
return $length;
|
||||||
|
break;
|
||||||
|
case 'tinyblob':
|
||||||
|
case 'tinytext':
|
||||||
|
return 255; // 2^8 - 1
|
||||||
|
break;
|
||||||
|
case 'blob':
|
||||||
|
case 'text':
|
||||||
|
return 65535; // 2^16 - 1
|
||||||
|
break;
|
||||||
|
case 'mediumblob':
|
||||||
|
case 'mediumtext':
|
||||||
|
return 16777215; // 2^24 - 1
|
||||||
|
break;
|
||||||
|
case 'longblob':
|
||||||
|
case 'longtext':
|
||||||
|
return 4294967295; // 2^32 - 1
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a string is ASCII.
|
* Check if a string is ASCII.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue