Skip to content

Commit

Permalink
[Debug] Improve keyword highlighting and escaping of query strings
Browse files Browse the repository at this point in the history
* Sort highlighted keywords alphabetically.

* Add new composite keywords.

* Deconstruct composite keywords.

* Add basic test for query highlighting in toolbar.

* Ignore keywords in string values of queries.

* Use generic table and column names for tests.

* Add credits for regex pattern.

* Escape HTML entities when formatting query string.

* Use esc() for escaping query string.
  • Loading branch information
sfadschm authored Oct 16, 2021
1 parent 0045a6f commit 2007d64
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 23 deletions.
53 changes: 30 additions & 23 deletions system/Database/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -367,46 +367,53 @@ public function debugToolbarDisplay(): string
{
// Key words we want bolded
static $highlight = [
'SELECT',
'DISTINCT',
'FROM',
'WHERE',
'AND',
'LEFT JOIN',
'RIGHT JOIN',
'JOIN',
'ORDER BY',
'AS',
'ASC',
'AVG',
'BY',
'COUNT',
'DESC',
'GROUP BY',
'LIMIT',
'INSERT',
'INTO',
'VALUES',
'UPDATE',
'OR',
'DISTINCT',
'FROM',
'GROUP',
'HAVING',
'OFFSET',
'NOT IN',
'IN',
'INNER',
'INSERT',
'INTO',
'IS',
'JOIN',
'LEFT',
'LIKE',
'NOT LIKE',
'COUNT',
'LIMIT',
'MAX',
'MIN',
'NOT',
'NULL',
'OFFSET',
'ON',
'AS',
'AVG',
'OR',
'ORDER',
'RIGHT',
'SELECT',
'SUM',
'UPDATE',
'VALUES',
'WHERE',
];

if (empty($this->finalQueryString)) {
$this->compileBinds(); // @codeCoverageIgnore
}

$sql = $this->finalQueryString;
$sql = esc($this->finalQueryString);

$search = '/\b(?:' . implode('|', $highlight) . ')\b/';
/**
* @see https://stackoverflow.com/a/20767160
* @see https://regex101.com/r/hUlrGN/4
*/
$search = '/\b(?:' . implode('|', $highlight) . ')\b(?![^(')]*'(?:(?:[^(')]*'){2})*[^(')]*$)/';

return preg_replace_callback($search, static function ($matches) {
return '<strong>' . str_replace(' ', '&nbsp;', $matches[0]) . '</strong>';
Expand Down
33 changes: 33 additions & 0 deletions tests/system/Database/BaseQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -363,4 +363,37 @@ public function testSetQueryBinds()

$this->assertSame($expected, $query->getQuery());
}

public function queryKeywords()
{
return [
'highlightKeyWords' => [
'<strong>SELECT</strong> `a`.*, `b`.`id` <strong>AS</strong> `b_id` <strong>FROM</strong> `a` <strong>LEFT</strong> <strong>JOIN</strong> `b` <strong>ON</strong> `b`.`a_id` = `a`.`id` <strong>WHERE</strong> `b`.`id` <strong>IN</strong> (&#039;1&#039;) <strong>AND</strong> `a`.`deleted_at` <strong>IS</strong> <strong>NOT</strong> <strong>NULL</strong> <strong>LIMIT</strong> 1',
'SELECT `a`.*, `b`.`id` AS `b_id` FROM `a` LEFT JOIN `b` ON `b`.`a_id` = `a`.`id` WHERE `b`.`id` IN (\'1\') AND `a`.`deleted_at` IS NOT NULL LIMIT 1',
],
'ignoreKeyWordsInValues' => [
'<strong>SELECT</strong> * <strong>FROM</strong> `a` <strong>WHERE</strong> `a`.`col` = &#039;SELECT escaped keyword in value&#039; <strong>LIMIT</strong> 1',
'SELECT * FROM `a` WHERE `a`.`col` = \'SELECT escaped keyword in value\' LIMIT 1',
],
'escapeHtmlValues' => [
'<strong>SELECT</strong> &#039;&lt;s&gt;&#039; <strong>FROM</strong> dual',
'SELECT \'<s>\' FROM dual',
],
];
}

/**
* @dataProvider queryKeywords
*
* @param mixed $expected
* @param mixed $sql
*/
public function testHighlightQueryKeywords($expected, $sql)
{
$query = new Query($this->db);
$query->setQuery($sql);
$query->getQuery();

$this->assertSame($expected, $query->debugToolbarDisplay());
}
}

0 comments on commit 2007d64

Please sign in to comment.