Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
I'm not completely sure what circumstance I created that caused this; I think it's entirely because the 'delta' I provided is > 32 characters and it gets cut off in the database. When this happens, block_rehash gets confused with non-matching deltas, and when it tries to unconfuse itself, it executes this block of code:
if (empty($old_blocks[$module][$delta])) {
// If it's a new block, add identifiers.
$block['module'] = $module;
$block['delta'] = $delta;
$block['theme'] = $theme_key;
if (!isset($block['pages'])) {
// {block}.pages is type 'text', so it cannot have a
// default value, and not null, so we need to provide
// value if the module did not.
$block['pages'] = '';
}
// Add defaults and save it into the database.
drupal_write_record('blocks', $block);
// Set region to none if not enabled.
$block['region'] = $block['status'] ? $block['region'] : BLOCK_REGION_NONE;
// Add to the list of blocks we return.
$blocks[] = $block;
}
The problem with the above is that drupal_write_record() converts $block into an object, and the line of code immediately after causes a whitescreen with the following error:
Fatal error: Cannot use object of type stdClass as array in var/www/views2/modules/block/block.module on line 263
The attached patch casts the converted object back to an array.
Comment | File | Size | Author |
---|---|---|---|
#1 | block_delta.tar_.gz | 529 bytes | deviantintegral |
fix-block.patch | 826 bytes | merlinofchaos | |
Comments
Comment #1
deviantintegral CreditAttribution: deviantintegral commentedI took a look at this and can't seem to replicate it exactly. I do get all kinds of problems if I have a block where the delta is 33 characters or more. As soon as you load admin/build/block a second time, you get the following error:
user warning: Duplicate entry 'garland-block_delta-thirty_three_character_block_dlt' for key 2 query: INSERT INTO blocks (module, delta, theme, status, weight, region, custom, throttle, visibility, pages, title, cache) VALUES ('block_delta', 'thirty_three_character_block_dlta', 'garland', 0, 0, '', 0, 0, 0, '', '', 1) in /home/drupal6/www/includes/common.inc on line 3324.
Where the block name is
thirty_three_character_block_dlta
. As well, the "new block" code does get triggered on every call to _block_rehash, but in my case the array isn't converted to an object in the reference, so I don't get a white screen. I'm not incredibly familiar with PHP references, but I don't see why the object wouldn't be converted since it does appear to be passed by reference.At the very least, I think the documentation should be updated to note the 32 character limit. I've also attached a simple module with a 33 character delta for testing.
--Andrew
Comment #2
deviantintegral CreditAttribution: deviantintegral commentedI would appreciate some feedback as to if this needs to be fixed in block.module or should just be a documentation update for module developers.
Comment #3
dpearcefl CreditAttribution: dpearcefl commentedHas this been fixed in the latest D6?
Comment #4
dpearcefl CreditAttribution: dpearcefl commentedComment #5
adamdicarlo CreditAttribution: adamdicarlo commenteddrupal_write_record() has been fixed -- "// If we began with an array, convert back so we don't surprise the caller." This code path doesn't white-screen.
However, there's still the problem of >32 character block deltas causing _block_rehash() to try to write duplicate rows. The invocation of hook_block() needs to truncate $delta. Of course that means *every* invocation should do that, too. Not really sure this bug is worth fixing at this point, in either D6 or D7 (haven't tried it out but code-wise it looks like the bug is in D7, too)...