node_view() modifies the node object stored in the menu

neochief - January 16, 2009 - 12:26
Project:Drupal
Version:7.x-dev
Component:node system
Category:bug report
Priority:normal
Assigned:Unassigned
Status:duplicate
Description

Hello

Bug can be reproduced by following these steps:
1. Create a node.
2. Create a block with PHP input and content (or use any other method to output this code):

<?php
  print_r
(menu_get_object('node'));
?>

Make sure that block will be shown at your's node.
3. Go to your node.

You should see a printed $node object structure (from block's code). Pay attention that in this object will be a "content" property, which can only be created by node_view(). And it would be not so bad, if "teaser" property been there too. But it's missing. It's removing at node_view().

Solution:

As you may know, menu_execute_active_handler() is passing loaded objects from page_arguments into page_callback. This object lives unchanged until it arrives to node_view():

function node_view($node, $teaser = FALSE) {
  $node = (object)$node;

  $node = node_build_content($node, $teaser, $page);
  ...

As object are passing ONLY by reference, we're getting node_build_content() changes out node object.

The solution of this problem is to clone objects passing to node_view():

function node_view($node, $teaser = FALSE) {
  if (is_object($node)) {
    $node = drupal_clone($node);
  }
  else {
    $node = (object)$node;
  }

  $node = node_build_content($node, $teaser, $page);
  ...

In this case, everyting works perfectly.

Attaching patches for fixing it in D6&7.

AttachmentSizeStatusTest resultOperations
node_D6.patch498 bytesIgnoredNoneNone
node_D7.patch624 bytesIdleFailed: Failed to apply patch.View details | Re-test

#1

neochief - January 16, 2009 - 12:27

P.S. Thanks to MITSUFAN for his help in catching this bug.

#2

neochief - January 16, 2009 - 12:27
Status:active» needs review

#3

Damien Tournoud - January 16, 2009 - 12:30
Title:node_view() rewrites router items data» node_view() modifies the node object stored in the menu

I'm not quite sure this is a bug and I'm -1 on the solution. We really don't need to use even more memory for this.

#4

neochief - January 16, 2009 - 12:38

As alternative, we could not remove teaser and body from node object during node_view (as I see, it's only related to 6x, because in 7x nothing is removed). But I'm not sure if everything will works fine when they will both stay. I'll try to check.

#5

System Message - January 16, 2009 - 12:50
Status:needs review» needs work

The last submitted patch failed testing.

#6

catch - January 16, 2009 - 13:08

There's a general issue at #154859: Document that objects are shared between modules - does that make this a duplicate?

#7

neochief - January 16, 2009 - 13:23

Yes, you're right, it's related to #154859: Document that objects are shared between modules. But I'm not sure that #154859 will get a solution in near future. I think It's too general. Anyway, I can move my patches there if there's a strong need.

#8

sun - November 2, 2009 - 18:37
Status:needs work» duplicate

Marking as duplicate of #154859: Document that objects are shared between modules

 
 

Drupal is a registered trademark of Dries Buytaert.