Explorar o código

Improved regex for SQL group, order, from

Enrico Zimuel %!s(int64=11) %!d(string=hai) anos
pai
achega
d8785057e1
Modificáronse 2 ficheiros con 25 adicións e 3 borrados
  1. 3 3
      library/Zend/Db/Select.php
  2. 22 0
      tests/Zend/Db/Select/StaticTest.php

+ 3 - 3
library/Zend/Db/Select.php

@@ -509,7 +509,7 @@ class Zend_Db_Select
         }
 
         foreach ($spec as $val) {
-            if (preg_match('/\(.*\)/', (string) $val)) {
+            if (preg_match('/^[\w]*\([^\)]*\)$/', (string) $val)) {
                 $val = new Zend_Db_Expr($val);
             }
             $this->_parts[self::GROUP][] = $val;
@@ -601,7 +601,7 @@ class Zend_Db_Select
                     $val = trim($matches[1]);
                     $direction = $matches[2];
                 }
-                if (preg_match('/^[\w]*\(.*\)$/', $val)) {
+                if (preg_match('/^[\w]*\([^\)]*\)$/', $val)) {
                     $val = new Zend_Db_Expr($val);
                 }
                 $this->_parts[self::ORDER][] = array($val, $direction);
@@ -943,7 +943,7 @@ class Zend_Db_Select
                     $alias = $m[2];
                 }
                 // Check for columns that look like functions and convert to Zend_Db_Expr
-                if (preg_match('/\(.*\)/', $col)) {
+                if (preg_match('/^[\w]*\([^\)]*\)$/', $col)) {
                     $col = new Zend_Db_Expr($col);
                 } elseif (preg_match('/(.+)\.(.+)/', $col, $m)) {
                     $currentCorrelationName = $m[1];

+ 22 - 0
tests/Zend/Db/Select/StaticTest.php

@@ -830,6 +830,28 @@ class Zend_Db_Select_StaticTest extends Zend_Db_Select_TestCommon
         $select = $this->_db->select();
         $select->from(array('p' => 'products'))->order('name;select;MD5(1)');
         $this->assertEquals('SELECT "p".* FROM "products" AS "p" ORDER BY "name;select;MD5(1)" ASC', $select->assemble());
+
+        $select = $this->_db->select();
+        $select->from(array('p' => 'products'))->order('MD5(1);drop table products; -- )');
+        $this->assertEquals('SELECT "p".* FROM "products" AS "p" ORDER BY "MD5(1);drop table products; -- )" ASC', $select->assemble());
+    }
+
+    public function testSqlInjectionWithGroup()
+    {
+        $select = $this->_db->select();
+        $select->from(array('p' => 'products'))->group('ABS("weight")');
+        $this->assertEquals('SELECT "p".* FROM "products" AS "p" GROUP BY ABS("weight")', $select->assemble());
+
+        $select = $this->_db->select();
+        $select->from(array('p' => 'products'))->group('MD5(1); drop table products; -- )');
+        $this->assertEquals('SELECT "p".* FROM "products" AS "p" GROUP BY "MD5(1); drop table products; -- )"', $select->assemble());
+    }
+
+    public function testSqlInjectionInColumn()
+    {
+        $select = $this->_db->select();
+        $select->from(array('p' => 'products'), array('MD5(1); drop table products; -- )'));
+        $this->assertEquals('SELECT "p"."MD5(1); drop table products; -- )" FROM "products" AS "p"', $select->assemble());
     }
 
     /**