Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.1151 diff -u -r1.1151 common.inc --- includes/common.inc 24 Apr 2010 14:53:59 -0000 1.1151 +++ includes/common.inc 26 Apr 2010 20:57:30 -0000 @@ -5752,7 +5752,7 @@ } // Build array of fields to update or insert. - if (empty($info['serialize'])) { + if ($info['type'] != 'blob' || empty($info['serialize'])) { $fields[$field] = $object->$field; } elseif (isset($object->$field)) { Index: includes/menu.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/menu.inc,v retrieving revision 1.387 diff -u -r1.387 menu.inc --- includes/menu.inc 26 Apr 2010 14:06:23 -0000 1.387 +++ includes/menu.inc 26 Apr 2010 20:57:30 -0000 @@ -2687,23 +2687,7 @@ $menu_name = $item['menu_name']; if (!$existing_item) { - $item['mlid'] = db_insert('menu_links') - ->fields(array( - 'menu_name' => $item['menu_name'], - 'plid' => $item['plid'], - 'link_path' => $item['link_path'], - 'hidden' => $item['hidden'], - 'external' => $item['external'], - 'has_children' => $item['has_children'], - 'expanded' => $item['expanded'], - 'weight' => $item['weight'], - 'module' => $item['module'], - 'link_title' => $item['link_title'], - 'options' => serialize($item['options']), - 'customized' => $item['customized'], - 'updated' => $item['updated'], - )) - ->execute(); + drupal_write_record('menu_links', $item); } // Directly fill parents for top-level links. @@ -2750,34 +2734,7 @@ // $item may have additional keys left over from building a router entry. // The intersect removes the extra keys, allowing a meaningful comparison. if (!$existing_item || (array_intersect_assoc($item, $existing_item)) != $existing_item) { - db_update('menu_links') - ->fields(array( - 'menu_name' => $item['menu_name'], - 'plid' => $item['plid'], - 'link_path' => $item['link_path'], - 'router_path' => $item['router_path'], - 'hidden' => $item['hidden'], - 'external' => $item['external'], - 'has_children' => $item['has_children'], - 'expanded' => $item['expanded'], - 'weight' => $item['weight'], - 'depth' => $item['depth'], - 'p1' => $item['p1'], - 'p2' => $item['p2'], - 'p3' => $item['p3'], - 'p4' => $item['p4'], - 'p5' => $item['p5'], - 'p6' => $item['p6'], - 'p7' => $item['p7'], - 'p8' => $item['p8'], - 'p9' => $item['p9'], - 'module' => $item['module'], - 'link_title' => $item['link_title'], - 'options' => serialize($item['options']), - 'customized' => $item['customized'], - )) - ->condition('mlid', $item['mlid']) - ->execute(); + drupal_write_record('menu_links', $item, 'mlid'); // Check the has_children status of the parent. _menu_update_parental_status($item); menu_cache_clear($menu_name); Index: modules/dblog/dblog.install =================================================================== RCS file: /cvs/drupal/drupal/modules/dblog/dblog.install,v retrieving revision 1.20 diff -u -r1.20 dblog.install --- modules/dblog/dblog.install 4 Dec 2009 16:49:46 -0000 1.20 +++ modules/dblog/dblog.install 26 Apr 2010 20:57:30 -0000 @@ -38,9 +38,10 @@ 'description' => 'Text of log message to be passed into the t() function.', ), 'variables' => array( - 'type' => 'text', + 'type' => 'blob', 'not null' => TRUE, 'size' => 'big', + 'serialize' => TRUE, 'description' => 'Serialized array of variables that match the message string and that is passed into the t() function.', ), 'severity' => array( @@ -137,6 +138,23 @@ } /** + * Convert serialized fields to blob. + */ +function dblog_update_7004() { + // 'text' column type doesn't reliably hold serialized variables. Convert to 'blob'. See http://drupal.org/node/690746 + // See database_test.test: DatabaseTestCase + + $spec = array( + 'type' => 'blob', + 'not null' => TRUE, + 'size' => 'big', + 'serialize' => TRUE, + 'description' => 'Serialized array of variables that match the message string and that is passed into the t() function.', + ); + db_change_field('watchdog', 'variables', 'variables', $spec); +} + +/** * @} End of "defgroup updates-6.x-to-7.x" * The next series of updates should start at 8000. */ Index: modules/field/field.install =================================================================== RCS file: /cvs/drupal/drupal/modules/field/field.install,v retrieving revision 1.18 diff -u -r1.18 field.install --- modules/field/field.install 27 Mar 2010 05:52:49 -0000 1.18 +++ modules/field/field.install 26 Apr 2010 20:57:30 -0000 @@ -72,8 +72,8 @@ 'description' => '@TODO', ), 'data' => array( - 'type' => 'text', - 'size' => 'medium', + 'type' => 'blob', + 'size' => 'big', 'not null' => TRUE, 'serialize' => TRUE, 'description' => 'Serialized data containing the field properties that do not warrant a dedicated column.', @@ -143,8 +143,8 @@ 'default' => '' ), 'data' => array( - 'type' => 'text', - 'size' => 'medium', + 'type' => 'blob', + 'size' => 'big', 'not null' => TRUE, 'serialize' => TRUE, ), Index: modules/filter/filter.install =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.install,v retrieving revision 1.36 diff -u -r1.36 filter.install --- modules/filter/filter.install 22 Apr 2010 05:44:41 -0000 1.36 +++ modules/filter/filter.install 26 Apr 2010 20:57:30 -0000 @@ -46,7 +46,7 @@ 'description' => 'Filter enabled status. (1 = enabled, 0 = disabled)', ), 'settings' => array( - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, 'size' => 'big', 'serialize' => TRUE, @@ -422,6 +422,23 @@ } /** + * Convert serialized fields to blob. + */ +function filter_update_7009() { + // 'text' column type doesn't reliably hold serialized variables. Convert to 'blob'. See http://drupal.org/node/690746 + // See database_test.test: DatabaseTestCase + + $spec = array( + 'type' => 'blob', + 'not null' => FALSE, + 'size' => 'big', + 'serialize' => TRUE, + 'description' => 'A serialized array of name value pairs that store the filter settings for the specific format.', + ); + db_change_field('filter', 'settings', 'settings', $spec); +} + +/** * @} End of "defgroup updates-6.x-to-7.x" * The next series of updates should start at 8000. */ Index: modules/image/image.install =================================================================== RCS file: /cvs/drupal/drupal/modules/image/image.install,v retrieving revision 1.8 diff -u -r1.8 image.install --- modules/image/image.install 9 Apr 2010 12:07:12 -0000 1.8 +++ modules/image/image.install 26 Apr 2010 20:57:30 -0000 @@ -86,7 +86,7 @@ ), 'data' => array( 'description' => 'The configuration data for the effect.', - 'type' => 'text', + 'type' => 'blob', 'not null' => TRUE, 'size' => 'big', 'serialize' => TRUE, Index: modules/rdf/rdf.install =================================================================== RCS file: /cvs/drupal/drupal/modules/rdf/rdf.install,v retrieving revision 1.3 diff -u -r1.3 rdf.install --- modules/rdf/rdf.install 26 Feb 2010 18:31:29 -0000 1.3 +++ modules/rdf/rdf.install 26 Apr 2010 20:57:30 -0000 @@ -27,7 +27,7 @@ ), 'mapping' => array( 'description' => 'The serialized mapping of the bundle type and fields to RDF terms.', - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, 'size' => 'big', 'serialize' => TRUE, Index: modules/simpletest/tests/database_test.install =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/database_test.install,v retrieving revision 1.11 diff -u -r1.11 database_test.install --- modules/simpletest/tests/database_test.install 3 Mar 2010 08:40:25 -0000 1.11 +++ modules/simpletest/tests/database_test.install 26 Apr 2010 20:57:30 -0000 @@ -220,7 +220,7 @@ ), 'info' => array( 'description' => "The person's data in serialized form.", - 'type' => 'text', + 'type' => 'blob', 'serialize' => TRUE, ), ), Index: modules/simpletest/tests/database_test.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/database_test.test,v retrieving revision 1.87 diff -u -r1.87 database_test.test --- modules/simpletest/tests/database_test.test 11 Apr 2010 18:33:44 -0000 1.87 +++ modules/simpletest/tests/database_test.test 26 Apr 2010 20:57:31 -0000 @@ -629,6 +629,27 @@ $r = db_query('SELECT * FROM {test_two_blobs} WHERE id = :id', array(':id' => $id))->fetchAssoc(); $this->assertTrue($r['blob1'] === 'This is' && $r['blob2'] === 'a test', t('Can insert multiple blobs per row.')); } + + /** + * Test that we can insert serialized data into important fields. + */ + function testInsertSerializedData() { + // Alternative crash cases: + // 1) + // drupal_set_message("Please dont crash" . hash('md5', 'too late', TRUE)); + // drupal_exit(); + // 2) + // variable_set("dontcrash", "Please dont crash" . hash('md5', 'too late', TRUE)); + $name = "dontcrash"; + $value = "Please dont crash" . hash('md5', 'too late', TRUE); + try { + db_merge('variable')->key(array('name' => $name))->fields(array('value' => serialize($value)))->execute(); + $this->pass(t('Success! No PDO exception thrown.')); + } catch (Exception $e) { + $this->fail(t('Fail! Your serialized blobs are quite distraught.')); + } + + } } /** Index: modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.461 diff -u -r1.461 system.install --- modules/system/system.install 10 Apr 2010 17:30:15 -0000 1.461 +++ modules/system/system.install 26 Apr 2010 20:57:31 -0000 @@ -437,9 +437,10 @@ ), 'value' => array( 'description' => 'The value of the variable.', - 'type' => 'text', + 'type' => 'blob', 'not null' => TRUE, 'size' => 'big', + 'serialize' => TRUE, 'translatable' => TRUE, ), ), @@ -472,9 +473,10 @@ ), 'parameters' => array( 'description' => 'Parameters to be passed to the callback function.', - 'type' => 'text', + 'type' => 'blob', 'not null' => TRUE, 'size' => 'big', + 'serialize' => TRUE, ), 'label' => array( 'description' => 'Label of the action.', @@ -511,9 +513,10 @@ ), 'batch' => array( 'description' => 'A serialized array containing the processing data for the batch.', - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, 'size' => 'big', + 'serialize' => TRUE, ), ), 'primary key' => array('bid'), @@ -575,8 +578,9 @@ ), 'headers' => array( 'description' => 'Any custom HTTP headers to be added to cached data.', - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, + 'serialize' => TRUE, ), 'serialized' => array( 'description' => 'A flag to indicate whether content is serialized (1) or not (0).', @@ -845,13 +849,15 @@ ), 'load_functions' => array( 'description' => 'A serialized array of function names (like node_load) to be called to load an object corresponding to a part of the current path.', - 'type' => 'text', + 'type' => 'blob', 'not null' => TRUE, + 'serialize' => TRUE, ), 'to_arg_functions' => array( 'description' => 'A serialized array of function names (like user_uid_optional_to_arg) to be called to replace a part of the router path with another string.', - 'type' => 'text', + 'type' => 'blob', 'not null' => TRUE, + 'serialize' => TRUE, ), 'access_callback' => array( 'description' => 'The callback which determines the access to this router path. Defaults to user_access.', @@ -862,8 +868,9 @@ ), 'access_arguments' => array( 'description' => 'A serialized array of arguments for the access callback.', - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, + 'serialize' => TRUE, ), 'page_callback' => array( 'description' => 'The name of the function that renders the page.', @@ -874,8 +881,9 @@ ), 'page_arguments' => array( 'description' => 'A serialized array of arguments for the page callback.', - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, + 'serialize' => TRUE, ), 'delivery_callback' => array( 'description' => 'The name of the function that sends the result of the page_callback function to the browser.', @@ -1044,9 +1052,10 @@ ), 'options' => array( 'description' => 'A serialized array of options to be passed to the url() or l() function, such as a query string or HTML attributes.', - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, 'translatable' => TRUE, + 'serialize' => TRUE, ), 'module' => array( 'description' => 'The name of the module that generated this link.', @@ -1200,7 +1209,7 @@ 'description' => 'The queue name.', ), 'data' => array( - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, 'size' => 'big', 'serialize' => TRUE, @@ -1379,9 +1388,10 @@ ), 'session' => array( 'description' => 'The serialized contents of $_SESSION, an array of name/value pairs that persists across page requests by this session ID. Drupal loads $_SESSION from here at the start of each request and saves it at the end.', - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, 'size' => 'big', + 'serialize' => TRUE, ), ), 'primary key' => array('sid'), @@ -1455,8 +1465,9 @@ ), 'info' => array( 'description' => "A serialized array containing information from the module's .info file; keys can include name, description, package, version, core, dependencies, dependents, and php.", - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, + 'serialize' => TRUE, ), ), 'primary key' => array('filename'), @@ -2398,6 +2409,100 @@ } /** + * Convert serialized fields to blob. + */ +function system_update_7053() { + // 'text' column type doesn't reliably hold serialized variables. Convert to 'blob'. See http://drupal.org/node/690746 + // See database_test.test: DatabaseTestCase + + $spec = array( + 'description' => 'The value of the variable.', + 'type' => 'blob', + 'not null' => TRUE, + 'size' => 'big', + 'serialize' => TRUE, + 'translatable' => TRUE, + ); + db_change_field('variable', 'value', 'value', $spec); + + $spec = array( + 'description' => 'Parameters to be passed to the callback function.', + 'type' => 'blob', + 'not null' => TRUE, + 'size' => 'big', + 'serialize' => TRUE, + ); + db_change_field('actions', 'parameters', 'parameters', $spec); + + $spec = array( + 'description' => 'A serialized array containing the processing data for the batch.', + 'type' => 'blob', + 'not null' => FALSE, + 'size' => 'big', + 'serialize' => TRUE, + ); + db_change_field('batch', 'batch', 'batch', $spec); + + $spec = array( + 'description' => 'A serialized array of function names (like node_load) to be called to load an object corresponding to a part of the current path.', + 'type' => 'blob', + 'not null' => TRUE, + 'serialize' => TRUE, + ); + db_change_field('menu_router', 'load_functions', 'load_functions', $spec); + + $spec = array( + 'description' => 'A serialized array of function names (like user_uid_optional_to_arg) to be called to replace a part of the router path with another string.', + 'type' => 'blob', + 'not null' => TRUE, + 'serialize' => TRUE, + ); + db_change_field('menu_router', 'to_arg_functions', 'to_arg_functions', $spec); + + $spec = array( + 'description' => 'A serialized array of arguments for the access callback.', + 'type' => 'blob', + 'not null' => FALSE, + 'serialize' => TRUE, + ); + db_change_field('menu_router', 'access_arguments', 'access_arguments', $spec); + + $spec = array( + 'description' => 'A serialized array of arguments for the page callback.', + 'type' => 'blob', + 'not null' => FALSE, + 'serialize' => TRUE, + ); + db_change_field('menu_router', 'page_arguments', 'page_arguments', $spec); + + $spec = array( + 'description' => 'A serialized array of options to be passed to the url() or l() function, such as a query string or HTML attributes.', + 'type' => 'blob', + 'not null' => FALSE, + 'translatable' => TRUE, + 'serialize' => TRUE, + ); + db_change_field('menu_links', 'options', 'options', $spec); + + $spec = array( + 'description' => 'The serialized contents of $_SESSION, an array of name/value pairs that persists across page requests by this session ID. Drupal loads $_SESSION from here at the start of each request and saves it at the end.', + 'type' => 'blob', + 'not null' => FALSE, + 'size' => 'big', + 'serialize' => TRUE, + ); + db_change_field('sessions', 'session', 'session', $spec); + + $spec = array( + 'description' => "A serialized array containing information from the module's .info file; keys can include name, description, package, version, core, dependencies, dependents, and php.", + 'type' => 'blob', + 'not null' => FALSE, + 'serialize' => TRUE, + ); + db_change_field('system', 'info', 'info', $spec); +} + +/** * @} End of "defgroup updates-6.x-to-7.x" * The next series of updates should start at 8000. */ Index: modules/user/user.install =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.install,v retrieving revision 1.45 diff -u -r1.45 user.install --- modules/user/user.install 13 Apr 2010 15:15:07 -0000 1.45 +++ modules/user/user.install 26 Apr 2010 20:57:31 -0000 @@ -212,7 +212,7 @@ 'description' => 'Email address used for initial account creation.', ), 'data' => array( - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, 'size' => 'big', 'serialize' => TRUE, @@ -590,6 +590,23 @@ } /** + * Convert serialized fields to blob. + */ +function user_update_7008() { + // 'text' column type doesn't reliably hold serialized variables. Convert to 'blob'. See http://drupal.org/node/690746 + // See database_test.test: DatabaseTestCase + + $spec = array( + 'type' => 'blob', + 'not null' => FALSE, + 'size' => 'big', + 'serialize' => TRUE, + 'description' => 'A serialized array of name value pairs that are related to the user. Any form values posted during user edit are stored and are loaded into the $user object during user_load(). Use of this field is discouraged and it will likely disappear in a future version of Drupal.', + ); + db_change_field('users', 'data', 'data', $spec); +} + +/** * @} End of "defgroup user-updates-6.x-to-7.x" * The next series of updates should start at 8000. */