Browse Source

QueryLogger strips some characters from queries

Edgaras Janušauskas 9 years ago
parent
commit
1dec2bfc88
2 changed files with 33 additions and 1 deletions
  1. 13 1
      src/Database/Log/QueryLogger.php
  2. 20 0
      tests/TestCase/Database/Log/QueryLoggerTest.php

+ 13 - 1
src/Database/Log/QueryLogger.php

@@ -68,7 +68,19 @@ class QueryLogger
                 return $p ? '1' : '0';
             }
 
-            return is_string($p) ? "'$p'" : $p;
+            if (is_string($p)) {
+                $replacements = [
+                    '$' => '\\$',
+                    '\\' => '\\\\\\\\',
+                    "'" => "''",
+                ];
+
+                $p = strtr($p, $replacements);
+
+                return "'$p'";
+            }
+
+            return $p;
         }, $query->params);
 
         $keys = [];

+ 20 - 0
tests/TestCase/Database/Log/QueryLoggerTest.php

@@ -128,6 +128,26 @@ class QueryLoggerTest extends TestCase
     }
 
     /**
+     * Tests that placeholders are replaced with correctly escaped strings
+     *
+     * @return void
+     */
+    public function testStringInterpolationSpecialChars()
+    {
+        $logger = $this->getMockBuilder('\Cake\Database\Log\QueryLogger')
+            ->setMethods(['_log'])
+            ->getMock();
+        $query = new LoggedQuery;
+        $query->query = 'SELECT a FROM b where a = :p1 AND b = :p2 AND c = :p3 AND d = :p4';
+        $query->params = ['p1' => '$2y$10$dUAIj', 'p2' => '$0.23', 'p3' => 'a\\0b\\1c\\d', 'p4' => "a'b"];
+
+        $logger->expects($this->once())->method('_log')->with($query);
+        $logger->log($query);
+        $expected = "duration=0 rows=0 SELECT a FROM b where a = '\$2y\$10\$dUAIj' AND b = '\$0.23' AND c = 'a\\\\0b\\\\1c\\\\d' AND d = 'a''b'";
+        $this->assertEquals($expected, (string)$query);
+    }
+
+    /**
      * Tests that the logged query object is passed to the built-in logger using
      * the correct scope
      *