Browse Source

Fix incorrectly quoted identifiers in order clauses

When order clauses are strings, we cannot safely quote identifiers as
they can be hard to find. If an order by string contains spaces assume
the developer knows what they are doing.

Refs #6805
Mark Story 10 years ago
parent
commit
c8863e2edb
2 changed files with 21 additions and 1 deletions
  1. 4 1
      src/Database/IdentifierQuoter.php
  2. 17 0
      tests/TestCase/Database/QueryTest.php

+ 4 - 1
src/Database/IdentifierQuoter.php

@@ -206,6 +206,9 @@ class IdentifierQuoter
     /**
      * Quotes identifiers in "order by" expression objects
      *
+     * Strings with spaces are treated as literal expressions
+     * and will not have identifiers quoted.
+     *
      * @param \Cake\Database\Expression\OrderByExpression $expression The expression to quote.
      * @return void
      */
@@ -216,7 +219,7 @@ class IdentifierQuoter
                 $field = $this->_driver->quoteIdentifier($field);
                 return $part;
             }
-            if (is_string($part)) {
+            if (is_string($part) && strpos($part, ' ') === false) {
                 return $this->_driver->quoteIdentifier($part);
             }
             return $part;

+ 17 - 0
tests/TestCase/Database/QueryTest.php

@@ -1436,6 +1436,23 @@ class QueryTest extends TestCase
     }
 
     /**
+     * Test that order() being a string works.
+     *
+     * @return void
+     */
+    public function testSelectOrderByString()
+    {
+        $query = new Query($this->connection);
+        $query->select(['id'])
+            ->from('articles')
+            ->order('id asc');
+        $result = $query->execute();
+        $this->assertEquals(['id' => 1], $result->fetch('assoc'));
+        $this->assertEquals(['id' => 2], $result->fetch('assoc'));
+        $this->assertEquals(['id' => 3], $result->fetch('assoc'));
+    }
+
+    /**
      * Tests that group by fields can be passed similar to select fields
      * and that it sends the correct query to the database
      *