Index: modules/filter/filter.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.admin.inc,v
retrieving revision 1.10
diff -u -p -r1.10 filter.admin.inc
--- modules/filter/filter.admin.inc	19 Feb 2008 14:07:21 -0000	1.10
+++ modules/filter/filter.admin.inc	7 Apr 2008 16:48:11 -0000
@@ -21,17 +21,11 @@ function filter_admin_overview() {
 
   $form = array('#tree' => TRUE);
   foreach ($formats as $id => $format) {
-    $roles = array();
-    foreach (user_roles() as $rid => $name) {
-      // Prepare a roles array with roles that may access the filter.
-      if (strstr($format->roles, ",$rid,")) {
-        $roles[] = $name;
-      }
-    }
+    $roles = user_roles(FALSE, 'use '. check_plain($format->name));
     $default = ($id == variable_get('filter_default_format', 1));
     $options[$id] = '';
     $form[$id]['name'] = array('#value' => $format->name);
-    $form[$id]['roles'] = array('#value' => $default ? t('All roles may use default format') : ($roles ? implode(', ', $roles) : t('No roles may use this format')));
+    $form[$id]['roles'] = array('#value' => $default ? t('All roles may use the default format') : ($roles ? implode(', ', $roles) : t('No roles may use this format')));
     $form[$id]['configure'] = array('#value' => l(t('configure'), 'admin/settings/filters/'. $id));
     $form[$id]['delete'] = array('#value' => $default ? '' : l(t('delete'), 'admin/settings/filters/delete/'. $id));
     $form[$id]['weight'] = array('#type' => 'weight', '#default_value' => $format->weight);
@@ -95,7 +89,7 @@ function theme_filter_admin_overview($fo
 function filter_admin_format_page($format = NULL) {
   if (!isset($format->name)) {
     drupal_set_title(t("Add input format"));
-    $format = (object)array('name' => '', 'roles' => '', 'format' => '');
+    $format = (object)array('name' => '', 'format' => '');
   }
   return drupal_get_form('filter_admin_format_form', $format);
 }
@@ -108,9 +102,7 @@ function filter_admin_format_page($forma
  * @see filter_admin_format_form_submit()
  */
 function filter_admin_format_form(&$form_state, $format) {
-  $default = ($format->format == variable_get('filter_default_format', 1));
-  if ($default) {
-    $help = t('All roles for the default format must be enabled and cannot be changed.');
+  if ($format->format == variable_get('filter_default_format', 1)) {
     $form['default_format'] = array('#type' => 'hidden', '#value' => 1);
   }
 
@@ -121,23 +113,6 @@ function filter_admin_format_form(&$form
     '#required' => TRUE,
   );
 
-  // Add a row of checkboxes for form group.
-  $form['roles'] = array('#type' => 'fieldset',
-    '#title' => t('Roles'),
-    '#description' => $default ? $help : t('Choose which roles may use this filter format. Note that roles with the "administer filters" permission can always use all the filter formats.'),
-    '#tree' => TRUE,
-  );
-
-  foreach (user_roles() as $rid => $name) {
-    $checked = strstr($format->roles, ",$rid,");
-    $form['roles'][$rid] = array('#type' => 'checkbox',
-      '#title' => $name,
-      '#default_value' => ($default || $checked),
-    );
-    if ($default) {
-      $form['roles'][$rid]['#disabled'] = TRUE;
-    }
-  }
   // Table with filters
   $all = filter_list_all();
   $enabled = filter_list_format($format->format);
@@ -195,7 +170,7 @@ function filter_admin_format_form_submit
   $name = trim($form_state['values']['name']);
   $cache = TRUE;
 
-  // Add a new filter format.
+  // Add a new input format.
   if (!$format) {
     $new = TRUE;
     db_query("INSERT INTO {filter_formats} (name) VALUES ('%s')", $name);
@@ -219,25 +194,10 @@ function filter_admin_format_form_submit
     }
   }
 
-  // We store the roles as a string for ease of use.
-  // We should always set all roles to TRUE when saving a default role.
-  // We use leading and trailing comma's to allow easy substring matching.
-  $roles = array();
-  if (isset($form_state['values']['roles'])) {
-    foreach ($form_state['values']['roles'] as $id => $checked) {
-      if ($checked) {
-        $roles[] = $id;
-      }
-    }
-  }
-  if (!empty($form_state['values']['default_format'])) {
-    $roles = ','. implode(',', array_keys(user_roles())) .',';
-  }
-  else {
-    $roles = ','. implode(',', $roles) .',';
-  }
+  // @todo: ensure that default format adds permission for all roles, and
+  // permissions are removed from previous format for all roles(?)
 
-  db_query("UPDATE {filter_formats} SET cache = %d, name='%s', roles = '%s' WHERE format = %d", $cache, $name, $roles, $format);
+  db_query("UPDATE {filter_formats} SET cache = %d, name='%s' WHERE format = %d", $cache, $name, $format);
 
   cache_clear_all($format .':', 'cache_filter', TRUE);
 
Index: modules/filter/filter.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.install,v
retrieving revision 1.7
diff -u -p -r1.7 filter.install
--- modules/filter/filter.install	15 Mar 2008 12:31:28 -0000	1.7
+++ modules/filter/filter.install	7 Apr 2008 16:48:11 -0000
@@ -64,13 +64,6 @@ function filter_schema() {
         'default' => '',
         'description' => t('Name of the input format (Filtered HTML).'),
       ),
-      'roles' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => t('A comma-separated string of roles; references {role}.rid.'), // This is bad since you can't use joins, nor index.
-      ),
       'cache' => array(
         'type' => 'int',
         'not null' => TRUE,
@@ -99,6 +92,11 @@ function filter_schema() {
 }
 
 /**
+ * @defgroup updates-6.x-to-7.x Filter updates from 6.x to 7.x
+ * @{
+ */
+
+/**
  * Add a weight column to the filter formats table.
  */
 function filter_update_7000() {
@@ -106,3 +104,34 @@ function filter_update_7000() {
   db_add_field($ret, 'filter_formats', 'weight', array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny'));
   return $ret;
 }
+
+/**
+ * Move filter format access to the user permissions handler.
+ */
+function filter_update_7001() {
+  $ret = array();
+  // Get list of roles to work with.
+  $result = db_query("SELECT rid FROM {role}");
+  while ($role = db_result($result)) {
+    $roles[$role] = $role;
+  }
+  
+  // Move role data from filter_formats to user permissions.
+  $result = db_query("SELECT name, roles FROM {filter_formats}");
+  while ($format = db_fetch_object($result)) {
+    $format_roles = explode(',', $format->roles);
+    foreach ($format_roles as $format_role) {
+      if (in_array($format_role, $roles)) {
+        $ret[] = update_sql("UPDATE {permission} SET perm = CONCAT(perm, ', use ". db_escape_string(check_plain($format->name)) ."') WHERE rid = ". $format_role);
+      }
+    }
+  }
+  // Finally, drop the roles field from filter_formats.
+  db_drop_field($ret, 'filter_formats', 'roles');
+  return $ret;
+}
+
+/**
+ * @} End of "defgroup updates-6.x-to-7.x"
+ * The next series of updates should start at 8000.
+ */
Index: modules/filter/filter.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v
retrieving revision 1.207
diff -u -p -r1.207 filter.module
--- modules/filter/filter.module	13 Mar 2008 21:26:08 -0000	1.207
+++ modules/filter/filter.module	7 Apr 2008 16:48:12 -0000
@@ -150,9 +150,16 @@ function filter_admin_format_title($form
  * Implementation of hook_perm().
  */
 function filter_perm() {
-  return array(
+  $perms = array(
     'administer filters' => t('Manage input formats and filters, and select which roles may use them. %warning', array('%warning' => t('Warning: Give to trusted roles only; this permission has security implications.'))),
   );
+  
+  // Generate permissions for each input format.
+  $result = db_query('SELECT * FROM {filter_formats} ORDER BY weight');
+  while ($format = db_fetch_object($result)) {
+    $perms['use '. check_plain($format->name)] = t('Use %input_format in forms when entering or editing content.', array('%input_format' => $format->name));
+  }
+  return $perms;
 }
 
 /**
@@ -283,35 +290,28 @@ function filter_filter_tips($delta, $for
 }
 
 /**
- * Retrieve a list of input formats.
+ * Retrieve a list of input formats the current user can use.
+ *
+ * @param $index
+ *   Optional format identifier. If provided, only this format object will be
+ *   returned. Otherwise all format objects in an array keyed by format ID.
  */
 function filter_formats($index = NULL) {
-  global $user;
   static $formats;
 
   // Administrators can always use all input formats.
-  $all = user_access('administer filters');
+  $access_all = user_access('administer filters');
+  $default_format = variable_get('filter_default_format', 1);
 
   if (!isset($formats)) {
     $formats = array();
-
-    $query = 'SELECT * FROM {filter_formats}';
-
-    // Build query for selecting the format(s) based on the user's roles.
-    $args = array();
-    if (!$all) {
-      $where = array();
-      foreach ($user->roles as $rid => $role) {
-        $where[] = "roles LIKE '%%,%d,%%'";
-        $args[] = $rid;
-      }
-      $query .= ' WHERE '. implode(' OR ', $where) .' OR format = %d';
-      $args[] = variable_get('filter_default_format', 1);
-    }
-
-    $result = db_query($query .' ORDER by weight', $args);
+    $result = db_query('SELECT * FROM {filter_formats} ORDER BY weight');
     while ($format = db_fetch_object($result)) {
-      $formats[$format->format] = $format;
+      if ($access_all || ($format->format == $default_format) || user_access('use '. check_plain($format->name))) {
+        // Always add the default input format, otherwise add the format if
+        // the user has access to it.
+        $formats[$format->format] = $format;
+      }
     }
   }
   if (isset($index)) {
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.244
diff -u -p -r1.244 system.install
--- modules/system/system.install	21 Mar 2008 08:52:25 -0000	1.244
+++ modules/system/system.install	7 Apr 2008 16:48:13 -0000
@@ -369,8 +369,8 @@ function system_install() {
   db_query("INSERT INTO {role} (name) VALUES ('%s')", 'anonymous user');
   db_query("INSERT INTO {role} (name) VALUES ('%s')", 'authenticated user');
 
-  db_query("INSERT INTO {permission} (rid, perm, tid) VALUES (%d, '%s', %d)", 1, 'access content', 0);
-  db_query("INSERT INTO {permission} (rid, perm, tid) VALUES (%d, '%s', %d)", 2, 'access comments, access content, post comments, post comments without approval', 0);
+  db_query("INSERT INTO {permission} (rid, perm, tid) VALUES (%d, '%s', %d)", 1, 'access content, use Filtered HTML', 0);
+  db_query("INSERT INTO {permission} (rid, perm, tid) VALUES (%d, '%s', %d)", 2, 'access comments, access content, post comments, post comments without approval, use Filtered HTML', 0);
 
   db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", 'theme_default', 's:7:"garland";');
   db_query("UPDATE {system} SET status = %d WHERE type = '%s' AND name = '%s'", 1, 'theme', 'garland');
@@ -381,8 +381,8 @@ function system_install() {
   db_query("INSERT INTO {node_access} (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, '%s', %d, %d, %d)", 0, 0, 'all', 1, 0, 0);
 
   // Add input formats.
-  db_query("INSERT INTO {filter_formats} (name, roles, cache) VALUES ('%s', '%s', %d)", 'Filtered HTML', ',1,2,', 1);
-  db_query("INSERT INTO {filter_formats} (name, roles, cache) VALUES ('%s', '%s', %d)", 'Full HTML', '', 1);
+  db_query("INSERT INTO {filter_formats} (name, cache) VALUES ('%s', %d)", 'Filtered HTML', 1);
+  db_query("INSERT INTO {filter_formats} (name, cache) VALUES ('%s', %d)", 'Full HTML', 1);
 
   // Enable filters for each input format.
 
