Fixed incorrect regexes for <table>.<column> names + added warning in mysqlColumnName...
authorMattias Michaux <mattias.michaux@gmail.com>
Wed, 27 Apr 2016 16:22:12 +0000 (18:22 +0200)
committerMattias Michaux <mattias.michaux@gmail.com>
Fri, 29 Apr 2016 05:42:04 +0000 (07:42 +0200)
CRM/Utils/Rule.php

index eeb97a291404a33eeb29811ab94a96467e63a52d..00af967bd3af18f2de6cce5b10b851a332580d2f 100644 (file)
@@ -93,9 +93,13 @@ class CRM_Utils_Rule {
    * @return bool
    */
   public static function mysqlColumnNameLoose($str) {
-    //  check the length.
-    // This check can be incorrect for the <table>.<column> format, which can be
+    // Check the length.
+    // This check is incorrect for the <table>.<column> format, which can be
     // a problem.
+    // But is quit difficult to check, as a dot is also a valid character in a
+    // column name. In that case backticks are needed, which will
+    // be escaped in the escape function, which lead to an icorrect name...
+    // So this function assumes there is only a column name.
     if (empty($str) || strlen($str) > 64) {
       return FALSE;
     }
@@ -111,16 +115,16 @@ class CRM_Utils_Rule {
    * @return bool
    */
   public static function mysqlColumnName($str) {
-    // Check the length.
-    if (empty($str) || strlen($str) > 64) {
+    // Check not empty.
+    if (empty($str)) {
       return FALSE;
     }
 
-    // Make sure it only contains valid characters (alphanumeric and underscores).
+    // Ensure it only contains valid characters (alphanumeric and underscores).
     //
     // MySQL permits column names that don't match this (eg containing spaces),
     // but CiviCRM won't create those ...
-    if (!preg_match('/^[\w]+(\.[\w]+)?$/i', $str)) {
+    if (!preg_match('/^\w{1,64}(\.\w{1,64})?$/i', $str)) {
       return FALSE;
     }
 
@@ -154,7 +158,7 @@ class CRM_Utils_Rule {
     // at all, so we split and loop over.
     $parts = explode(',', $str);
     foreach ($parts as $part) {
-      if (!preg_match('/^(([\w]+)((\.)([\w]+))?( (asc|desc))?)$/i', trim($part))) {
+      if (!preg_match('/^((\w{1,64})((\.)(\w{1,64}))?( (asc|desc))?)$/i', trim($part))) {
         return FALSE;
       }
     }