diff -urN ./composite.module /var/www/drupal-installation-profiles/testing/modules/contrib/composite/composite.module
--- ./composite.module	2009-09-12 06:56:17.000000000 +0000
+++ /var/www/drupal-installation-profiles/testing/modules/contrib/composite/composite.module	2010-04-19 17:21:49.000000000 +0000
@@ -454,35 +454,55 @@
         //   for other modules to do their processing first.
         $layout = composite_get_layout($node->composite_layout);
         if ($layout) {
-          $layout['data'] = $node->composite_layout_data;
-          $node->composite_content = composite_view($node, $layout, $node->composite_references);
-          foreach ($node->composite_content as $zone => $zone_item) {
-            $node->composite_content[$zone] = drupal_render($zone_item);
+          // Avoid infinite loops by temporary marking in a global variable
+          // we are currently rendering the node.
+          global $composite_being_rendered;
+
+          // Because the composite layout can be render other composite layouts
+          // inside itself, recursion can only be checked on a per-nid basis.
+          // The isset() statement will avoid PHP 5.3 errors.
+          if (!isset($composite_being_rendered)) {
+            $composite_being_rendered = array();
           }
 
-          // Add this layout's css, if any
-          if ($layout['css']) {
-            drupal_add_css($layout['css']);
+          if (!$composite_being_rendered[$node->nid]) {
+            // Mark our content as being rendered.
+            $composite_being_rendered[$node->nid] = TRUE;
+
+            $layout['data'] = $node->composite_layout_data;
+            $node->composite_content = composite_view($node, $layout, $node->composite_references);
+            foreach ($node->composite_content as $zone => $zone_item) {
+              $node->composite_content[$zone] = drupal_render($zone_item);
+            }
+  
+            // Add this layout's css, if any
+            if ($layout['css']) {
+              drupal_add_css($layout['css']);
+            }
+  
+            // Call the appropriate theme('composite_layout...', ...) function.
+            // However, because the number of arguments depends on the number
+            //   of zones in the layout layout, we have to use call_user_func_array
+            
+            // Add in the theme hook name and the first two arguments
+            $args = array(
+              'composite_layout_' . $layout['key'],  // theme hook
+              $layout,                               // layout
+              $node->composite_content               // composite_content
+            );
+  
+            // Now add an argument for the contents of each zone
+            foreach ($layout['zones'] as $zone => $unused) {
+              $args[] = $node->composite_content[$zone];
+            }
+            
+            // And call it
+            $node->body = call_user_func_array('theme', $args);
           }
 
-          // Call the appropriate theme('composite_layout...', ...) function.
-          // However, because the number of arguments depends on the number
-          //   of zones in the layout layout, we have to use call_user_func_array
-          
-          // Add in the theme hook name and the first two arguments
-          $args = array(
-            'composite_layout_' . $layout['key'],  // theme hook
-            $layout,                               // layout
-            $node->composite_content               // composite_content
-          );
-
-          // Now add an argument for the contents of each zone
-          foreach ($layout['zones'] as $zone => $unused) {
-            $args[] = $node->composite_content[$zone];
-          }
-          
-          // And call it
-          $node->body = call_user_func_array('theme', $args);          
+          // Rendering is finished, allow our node to be rendered again
+          // elsewhere on site.
+          $composite_being_rendered[$node->nid] = FALSE;
         }
       }
       break;
