MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Matthias Leich Date:May 10 2010 2:45pm
Subject:bzr commit into mysql-5.1-bugteam branch (matthias.leich:3377)
Bug#51057
View as plain text  
#At file:///work2/5.1/mysql-5.1-bugteam-5356/ based on revid:martin.hansson@stripped

 3377 Matthias Leich	2010-05-10
      Fix for Bug#51057 Weak code in diff_tables.inc can lead to 100% CPU consumption
      1. Add check if the tables to be compared exist
      2. Add check which ensures that we never go into the while loop
         with a value which is obvious wrong or might cause endless looping.
         (Assume the select on the information_schema gives from whatever
         reason a dangerous value)
      3. Minor beautification

    modified:
      mysql-test/include/diff_tables.inc
=== modified file 'mysql-test/include/diff_tables.inc'
--- a/mysql-test/include/diff_tables.inc	2009-05-21 20:03:53 +0000
+++ b/mysql-test/include/diff_tables.inc	2010-05-10 14:45:19 +0000
@@ -65,7 +65,7 @@ let $_diff_i=2;
 while ($_diff_i) {
 
   # Parse out any leading "master:" or "slave:" from the table
-  # specification and connect the appropriate server.
+  # specification and connect to the appropriate server.
   let $_diff_conn_master=`SELECT SUBSTR('$_diff_table', 1, 7) = 'master:'`;
   if ($_diff_conn_master) {
     let $_diff_table=`SELECT SUBSTR('$_diff_table', 8)`;
@@ -78,10 +78,17 @@ while ($_diff_i) {
   }
 
   # Sanity-check the input.
-  let $_diff_error= `SELECT '$_diff_table' NOT LIKE '_%._%'`;
-  if ($_diff_error) {
-    --echo !!!ERROR IN TEST: \$diff_table_$_diff_i='$_diff_table' is not in the form database.table
-    exit;
+  if (`SELECT '$_diff_table' NOT LIKE '_%._%'`) {
+    --echo !!!ERROR IN TEST: \$diff_table_$_diff_i='$_diff_table'
+    --echo                   is not in the form   database.table
+    --die
+  }
+
+  # Check if the table exists
+  if (`SELECT COUNT(*) = 0 FROM information_schema.tables
+       WHERE CONCAT(table_schema, '.', table_name) = '$_diff_table'`) {
+    --echo !!!ERROR IN TEST: The table '$_diff_table' does not exist
+    --die
   }
 
   # We need the output files to be sorted (so that diff_files does not
@@ -94,6 +101,30 @@ while ($_diff_i) {
                            FROM information_schema.columns
                            WHERE CONCAT(table_schema, '.', table_name) =
                                  '$_diff_table'`;
+
+  # The content of $_diff_column_index must be an integer >= 0.
+  # If not the following might happen:
+  # Result of SELECT | $_diff_column_index | dec $_diff_column_index
+  #    NULL          | empty string        | -1
+  #    ''            | empty string        | -1
+  #    'a1'          | a1                  | -1
+  #    '1a'          | 1a                  |  0
+  #    ........................
+  # (Bug#51057 Weak code in diff_tables.inc can lead to 100% CPU consumption)
+  # In case $i = 1 the soone following loop
+  # while ($i) {
+  #   ...
+  #   dec $i;
+  # }
+  # will never terminate.
+  if (`SELECT CAST(CAST('$_diff_column_index' AS UNSIGNED) AS CHAR(65))
+              <> '$_diff_column_index'
+           OR CAST('$_diff_column_index' AS UNSIGNED) < 1`) {
+    --echo !!!ERROR IN TEST: \$_diff_column_index is '$_diff_column_index'
+    --echo                   but must be an unsigned integer > 0
+    --die
+  }
+
   let $_diff_column_list=$_diff_column_index;
   dec $_diff_column_index;
   while ($_diff_column_index) {


Attachment: [text/bzr-bundle] bzr/matthias.leich@sun.com-20100510144519-90voea6u881erb3e.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (matthias.leich:3377)Bug#51057Matthias Leich10 May