Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.324
diff -u -p -r1.324 form.inc
--- includes/form.inc	14 Mar 2009 20:13:26 -0000	1.324
+++ includes/form.inc	26 Mar 2009 23:44:06 -0000
@@ -1927,7 +1927,22 @@ function form_process_text_format($eleme
     $element['#type'] = 'markup';
     $element['#theme'] = NULL;
     $element['#theme_wrapper'] = NULL;
-    $element['format'] = filter_form($element['#text_format'], 1, $element_parents);
+
+    if (filter_access($element['#text_format'])) {
+      $element['format'] = filter_form($element['#text_format'], 1, $element_parents);
+    }
+    else {
+      $element['value']['#access'] = FALSE;
+      $element['#markup'] = t('%title has been disabled because you do not have sufficient permissions to edit this field.', array('%title' => $element['#title']));
+      $element['#markup'] .= check_markup($element['#default_value'], $element['#text_format'], '', FALSE);
+
+      // Add fixed format.
+      $element['format'] = array(
+        '#type' => 'value',
+        '#value' => $element['#text_format'],
+        '#parents' => $element_parents,
+      );
+    }
 
     // We need to clear the #text_format from the new child otherwise we
     // would get into an infinite loop.
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1032
diff -u -p -r1.1032 node.module
--- modules/node/node.module	20 Mar 2009 19:18:10 -0000	1.1032
+++ modules/node/node.module	26 Mar 2009 23:44:14 -0000
@@ -291,8 +291,17 @@ function node_mark($nid, $timestamp) {
 
 /**
  * See if the user used JS to submit a teaser.
+ *
+ * Disables teaser feature if body field is disabled.
  */
 function node_teaser_js(&$form, &$form_state) {
+
+  // Disable teaser fields when body is disabled
+  if (isset($form['body']['value']['#access']) && $form['body']['value']['#access'] == FALSE) {
+    unset($form['teaser_js']);
+    unset($form_state['values']['teaser_js']);
+  }
+  
   if (isset($form_state['input']['teaser_js'])) {
     // Glue the teaser to the body.
     if (trim($form_state['values']['teaser_js'])) {
@@ -330,6 +339,12 @@ function node_teaser_js(&$form, &$form_s
 function node_teaser_include_verify(&$form, &$form_state) {
   $message = '';
 
+  // Disable teaser fields when body is disabled, form state needs to be unset so that it is ignored
+  if (isset($form['body']['value']['#access']) && $form['body']['value']['#access'] == FALSE) {
+    unset($form['teaser_include']);
+    unset($form_state['values']['teaser_include']);
+  }
+
   // $form_state['input'] is set only when the form is built for preview/submit.
   if (isset($form_state['input']['body']) && isset($form_state['values']['teaser_include']) && !$form_state['values']['teaser_include']) {
     // "teaser_include" checkbox is present and unchecked.
@@ -2312,11 +2327,6 @@ function node_access($op, $node, $accoun
   if (empty($account)) {
     $account = $user;
   }
-  // If the node is in a restricted format, disallow editing.
-  if ($op == 'update' && !filter_access($node->format)) {
-    return FALSE;
-  }
-
   if (user_access('bypass node access', $account)) {
     return TRUE;
   }
Index: modules/node/node.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.test,v
retrieving revision 1.17
diff -u -p -r1.17 node.test
--- modules/node/node.test	8 Mar 2009 04:25:04 -0000	1.17
+++ modules/node/node.test	26 Mar 2009 23:44:18 -0000
@@ -363,6 +363,107 @@ class PageEditTestCase extends DrupalWeb
     $this->assertText($edit['title'], t('Title displayed.'));
     $this->assertText($edit['body'], t('Body displayed.'));
   }
+  /**
+   * Test edit page with special text format.
+   *
+   * Test if a normal user is able to edit the page but is not allowed to change
+   * the fields which use a text format he's not allowed to use.
+   */
+  function testPageEditLimitedPermission() {
+    $admin_user = $this->drupalCreateUser(array('administer filters', 'edit any page content', 'create page content'));
+    $normal_user = $this->drupalCreateUser(array('edit any page content', 'create page content'));
+
+    $this->drupalLogout();
+    $this->drupalLogin($admin_user);
+
+    list($filtered, $full) = $this->checkFilterFormats();
+
+    // Create node to edit.
+    $edit = array();
+    $edit['title'] = $this->randomName(8);
+    $edit['body'] = $this->randomName(16);
+    $edit['body_format'] = $full;
+    $this->drupalPost('node/add/page', $edit, t('Save'));
+
+    // Check that the node exists in the database.
+    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $this->assertTrue($node, t('Node found in database.'));
+
+    // Check that "edit" link points to correct page.
+    $this->clickLink(t('Edit'));
+    $edit_url = url("node/$node->nid/edit", array('absolute' => true));
+    $actual_url = $this->getURL();
+    $this->assertEqual($edit_url, $actual_url, t('On edit page.'));
+
+    // Check that the title and body fields are displayed with the correct values.
+    $this->assertLink(t('Edit'), 0, t('Edit tab found.'));
+    $this->assertFieldByName('title', $edit['title'], t('Title field displayed.'));
+    $this->assertFieldByName('body', '<!--break-->' . $edit['body'], t('Body field displayed.'));
+
+    // Edit the content of the node.
+    $edit = array();
+    $edit['title'] = $this->randomName(8);
+    $edit['body'] = $this->randomName(16);
+    // Stay on the current page, without reloading.
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    // Check that the title and body fields are displayed with the updated values.
+    $this->assertText($edit['title'], t('Title displayed.'));
+    $this->assertText($edit['body'], t('Body displayed.'));
+
+    // Try to edit with normal user
+    $this->drupalLogout();
+    $this->drupalLogin($normal_user);
+
+    $this->drupalGet("node/$node->nid");
+
+    // Check that "edit" link points to correct page.
+    $this->clickLink(t('Edit'));
+    $edit_url = url("node/$node->nid/edit", array('absolute' => true));
+    $actual_url = $this->getURL();
+    $this->assertEqual($edit_url, $actual_url, t('On edit page.'));
+
+    // Check if body field is read only
+    $this->assertText($edit['body'], t('Body is displayed as text'));
+    $this->assertRaw(t('%title has been disabled because you do not have sufficient permissions to edit this field.', array('%title' => t('Body'))), t('Description is available'));
+
+    // Check if teaser is disabled
+    $this->assertNoFieldByXPath("//input[@class='teaser-button']", t('Join summary'), t('Join button is not available'));
+    $this->assertNoField('teaser_js', t('Teaser field is not available'));
+    $this->assertNoField('teaser_include', t('Teaser include checkbox is not available'));
+
+    // Try to "force" the change
+    $new_edit = array();
+    $new_edit['title'] = $this->randomName(8);
+    // Stay on the current page, without reloading.
+    $this->drupalPost(NULL, $new_edit, t('Save'));
+
+    // Check that only the title is displayed with the updated values, the body should use the old values
+    $this->assertText($new_edit['title'], t('New title displayed.'));
+    $this->assertText($edit['body'], t('Old body displayed.'));
+  }
+
+    /**
+   * Query the database to get the two basic formats.
+   *
+   * @return Array Array containing filtered and full filter ids.
+   */
+  function checkFilterFormats() {
+    $result = db_query('SELECT format, name FROM {filter_format}');
+
+    $filtered = -1;
+    $full = -1;
+    while ($format = db_fetch_object($result)) {
+      if ($format->name == 'Filtered HTML') {
+        $filtered = $format->format;
+      }
+      elseif ($format->name == 'Full HTML') {
+        $full = $format->format;
+      }
+    }
+
+    return array($filtered, $full);
+  }
 }
 
 class PagePreviewTestCase extends DrupalWebTestCase {
