diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 03e5880..3699aff 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -898,7 +898,28 @@ function variable_initialize($conf = array()) { } else { // Proceed with variable rebuild. - $variables = array_map('unserialize', db_query('SELECT name, value FROM {variable}')->fetchAllKeyed()); + $variables = array(); + // We can run into unparsable values + $err_variables = array(); + $rows = db_query('SELECT name, value FROM {variable}')->fetchAllKeyed(); + foreach ($rows as $name => $db_value) { + // Suppress the notice. + $value = @unserialize($db_value); + // If the unserialize call returned FALSE and the stored value is NOT a + // boolean false, list it in the report. + if ($value === FALSE && $db_value != serialize(FALSE) && !isset($conf[$name])) { + $err_variables[] = $name; + } + $variables[$name] = $value; + } + // We throw an exception before storing the variables otherwise + // this exception is only thrown once which is bad. + if (count($err_variables)) { + $t = get_t(); + $err_vars = join (", ", $err_variables); + $err_str = "The variable(s) '@err_vars' are unreadable and need to be fixed. Please read UPGRADE.txt on how to resolve this problem."; + throw new Exception($t($err_str, array('@err_vars' => $err_vars))); + } cache_set('variables', $variables, 'cache_bootstrap'); lock_release($name); } diff --git a/modules/simpletest/tests/bootstrap.test b/modules/simpletest/tests/bootstrap.test index 014fc94..7ebdc82 100644 --- a/modules/simpletest/tests/bootstrap.test +++ b/modules/simpletest/tests/bootstrap.test @@ -267,6 +267,35 @@ class BootstrapVariableTestCase extends DrupalWebTestCase { $this->assertIdentical(5, variable_get('simpletest_bootstrap_variable_test', 5), t('The default variable parameter is passed through correctly.')); } + /** + * Test for a corrupted variable. + */ + function testFaultyVariable() { + $name = 'simpletest_bootstrap_wrong_variable_test'; + $test_value = 'unserialized_value'; + + // We write a value directly to the database bypassing the serialization + // We cannot use drupal_write_record as that serializes the value + db_merge('variable')->key(array('name' => $name))->fields(array('value' => $test_value))->execute(); + + // Clear the variable cache to reread the new value + cache_clear_all('variables', 'cache_bootstrap'); + // Reseed the variables. This should load $name + variable_initialize(); + + // Value should be 'default_value'. + $value = variable_get($name, 'default_value'); + $this->assertNotEqual($value, $test_value, 'Variable set incorrectly returned default value'); + + // Show that when variable is set correctly it returns correctly. + variable_set($name, $test_value); + + cache_clear_all('variables', 'cache_bootstrap'); + variable_initialize(); + + $value = variable_get($name, 'default_value'); + $this->assertEqual($value, $test_value, 'Variable set correctly returns correct data'); + } } /**