diff --git a/lib/db/cortex.php b/lib/db/cortex.php index 04b63dd..7b45ead 100644 --- a/lib/db/cortex.php +++ b/lib/db/cortex.php @@ -2723,9 +2723,14 @@ public function prepareFilter($cond, $engine, $db, $fieldConf=null, $primary='id list($parts, $args) = $this->convertNamedParams($parts, $args); $ncond = []; foreach ($parts as &$part) { - // enhanced IN handling - if (is_int(strpos($part, '?'))) { + // arg handling + $argCount = substr_count($part, '?'); + if ($argCount > 1) { + // function parameters like `foo(?,?,?)` + $ncond = array_merge($ncond, array_splice($args, 0, $argCount)); + } elseif ($argCount === 1) { $val = array_shift($args); + // enhanced IN operator args expansion if (is_int($pos = strpos($part, ' IN ?'))) { if ($val instanceof CortexCollection) $val = $val->getAll('_id',TRUE); @@ -2734,7 +2739,9 @@ public function prepareFilter($cond, $engine, $db, $fieldConf=null, $primary='id $bindMarks = str_repeat('?,',count($val) - 1).'?'; $part = substr($part, 0, $pos).' IN ('.$bindMarks.') '; $ncond = array_merge($ncond, $val); - } elseif($val === null && + } + // comparison against NULL + elseif($val === null && preg_match('/((?:\S[\w\-]+\S.?)+)\s*'. '(!?==?)\s*(?:\?|:\w+)/i',$part,$match)) { $part = ' '.$match[1].' IS '.($match[2][0]=='!'?'NOT ':'').'NULL '; diff --git a/test/test_common.php b/test/test_common.php index 00b834d..c1517a4 100644 --- a/test/test_common.php +++ b/test/test_common.php @@ -199,7 +199,22 @@ function run() 10,20,30,40,50,60), 'merge multiple filters'); + $qp = new \DB\CortexQueryParser(); + + $test->expect( + $qp->prepareFilter(['foo > bar'],'sql', $f3->DB) === ['`foo` > `bar`'], + 'auto-escape fields' + ); + $test->expect( + $qp->prepareFilter(['created_at > DATE_SUB(NOW(), INTERVAL 1 DAY)'],'sql', $f3->DB) === ['`created_at` > DATE_SUB(NOW(), INTERVAL 1 DAY)'], + 'respect function when auto-escaping' + ); + $test->expect( + $qp->prepareFilter(['foo(?,?,3,?)',1,2,4],'sql', $f3->DB) === ['foo(?,?,3,?)',1,2,4], + 'query parser: correct function args' + ); + /////////////////////////////////// return $test->results(); } -} \ No newline at end of file +}