Uploaded image for project: 'phpBB3'
  1. phpBB3
  2. PHPBB3-8366

Detecting Duplicate Private Message Rules

    XMLWordPrintable

Details

    • Bug
    • Status: Closed (View Workflow)
    • Trivial
    • Resolution: Won't Fix
    • 3.0.5
    • 3.0.10-RC1
    • None
    • PHP Environment: 5.2.9
      Database: MySQL 5.1.33

    Description

      phpBB 3.0.5 Detecting Duplicate Private Message Rules:

      The current system for detecting duplicate message rules is not very good, nor is it efficient.

      Take, for example, a rule matching a sender's exact username (using the 'is user' option).

      I can make two rules which are identical except for in one I enter my username in all minuscules, like dog cow, and then the other one with majuscules, such as Dog Cow. The system will accept and save these two rules, even though logically, they are identical. Unfortunately, they are not physically identical since the 'rule_string' stored in the two rows differs. To prevent this, the username returned from the users table should be stored, rather than the exact string which the user had originally entered.

      Secondly, the query for detecting duplicate rules is quite ugly. Essentially, it is building a big SELECT statement with a whole menagerie of WHERE and AND clauses on multiple, unindexed columns.

      Therefore, I propose a change: instead of searching on all of these columns, why not make a composite of the $rule_ary, such as by using crc32() or md5()? This way, a new, indexed column such as rule_hash may be added, which stores the composite of all of the rule's variables, and a SELECT statement looking for potential duplicates would be more efficient.

      Here is my proposed patch:

      In file: /includes/ucp/ucp_pm_options.php

      CHANGE THESE LINES:

      $rule_ary = array(
      'user_id' => $user->data['user_id'],
      'rule_check' => $check_option,
      'rule_connection' => $rule_option,
      'rule_string' => $rule_string,
      'rule_user_id' => $rule_user_id,
      'rule_group_id' => $rule_group_id,
      'rule_action' => $action,
      'rule_folder_id' => $folder_id
      );

      $sql = 'SELECT rule_id
      FROM ' . PRIVMSGS_RULES_TABLE . '
      WHERE ' . $db->sql_build_array('SELECT', $rule_ary);
      $result = $db->sql_query($sql);
      $row = $db->sql_fetchrow($result);
      $db->sql_freeresult($result);

      if ($row)

      { trigger_error('RULE_ALREADY_DEFINED'); }


      TO THIS INSTEAD:

      $rule_ary = array(
      'user_id' => $user->data['user_id'],
      'rule_check' => $check_option,
      'rule_connection' => $rule_option,
      'rule_string' => $rule_string,
      'rule_user_id' => $rule_user_id,
      'rule_group_id' => $rule_group_id,
      'rule_action' => $action,
      'rule_folder_id' => $folder_id
      );

      $rule_hash = md5(serialize($rule_ary));

      $sql = 'SELECT rule_id
      FROM ' . PRIVMSGS_RULES_TABLE . "
      WHERE rule_hash = '" . $db->sql_escape($rule_hash) . "'";
      $result = $db->sql_query($sql);
      $row = $db->sql_fetchrow($result);
      $db->sql_freeresult($result);

      if ($row)
      { trigger_error('RULE_ALREADY_DEFINED'); }

      else

      { $rule_ary += array('rule_hash' => $rule_hash); }

      SQL schema changes:

      ALTER TABLE `phpbb_privmsgs_rules` ADD `rule_hash` VARCHAR( 32 ) NOT NULL;
      ALTER TABLE `phpbb_privmsgs_rules` ADD INDEX ( `rule_hash` );

      Date found: 02 June, 2009
      by Dog Cow

      Attachments

        Activity

          People

            igorw Igor Wiedler [X] (Inactive)
            Dog Cow Dog Cow
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: