Skip to content

Commit 2e5e855

Browse files
authored
Merge pull request #52 from magento/48-RawQuerySniff
#48: Move RawQuerySniff
2 parents 45a8c6d + f147ef5 commit 2e5e855

File tree

4 files changed

+244
-0
lines changed

4 files changed

+244
-0
lines changed

Magento/Sniffs/SQL/RawQuerySniff.php

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
/**
3+
* Copyright © Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Sniffs\SQL;
7+
8+
use PHP_CodeSniffer\Sniffs\Sniff;
9+
use PHP_CodeSniffer\Files\File;
10+
use PHP_CodeSniffer\Util\Tokens;
11+
12+
/**
13+
* Detects possible raw SQL queries.
14+
*/
15+
class RawQuerySniff implements Sniff
16+
{
17+
/**
18+
* String representation of warning.
19+
*
20+
* @var string
21+
*/
22+
protected $warningMessage = 'Possible raw SQL statement %s detected.';
23+
/**
24+
* Warning violation code.
25+
*
26+
* @var string
27+
*/
28+
protected $warningCode = 'FoundRawSql';
29+
/**
30+
* List of SQL statements.
31+
*
32+
* @var array
33+
*/
34+
protected $statements = [
35+
'SELECT',
36+
'UPDATE',
37+
'INSERT',
38+
'CREATE',
39+
'DELETE',
40+
'ALTER',
41+
'DROP',
42+
'TRUNCATE'
43+
];
44+
/**
45+
* List of query functions.
46+
*
47+
* @var array
48+
*/
49+
protected $queryFunctions = [
50+
'query'
51+
];
52+
/**
53+
* @inheritdoc
54+
*/
55+
public function register()
56+
{
57+
return array_merge(Tokens::$stringTokens, [T_HEREDOC, T_NOWDOC]);
58+
}
59+
/**
60+
* @inheritdoc
61+
*/
62+
public function process(File $phpcsFile, $stackPtr)
63+
{
64+
$tokens = $phpcsFile->getTokens();
65+
$ignoredTokens = array_merge([T_WHITESPACE, T_OPEN_PARENTHESIS], Tokens::$stringTokens);
66+
$prev = $tokens[$phpcsFile->findPrevious($ignoredTokens, $stackPtr - 1, null, true)];
67+
if ($prev['code'] === T_EQUAL
68+
|| ($prev['code'] === T_STRING && in_array($prev['content'], $this->queryFunctions))
69+
|| in_array($tokens[$stackPtr]['code'], [T_HEREDOC, T_NOWDOC])
70+
) {
71+
$trim = function ($str) {
72+
return trim(str_replace(['\'', '"'], '', $str));
73+
};
74+
75+
if (preg_match('/^(' . implode('|', $this->statements) . ')\s/i', $trim($tokens[$stackPtr]['content']))) {
76+
$phpcsFile->addWarning(
77+
$this->warningMessage,
78+
$stackPtr,
79+
$this->warningCode,
80+
[trim($tokens[$stackPtr]['content'])]
81+
);
82+
}
83+
}
84+
}
85+
}
+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
3+
class RawQueryTest
4+
{
5+
/**
6+
* @var \Magento\Framework\App\ResourceConnection
7+
*/
8+
private $connection;
9+
10+
public function __construct(Magento\Framework\App\ResourceConnection $connection)
11+
{
12+
$this->connection = $connection;
13+
}
14+
15+
private function insertOneRow($ccode, $county, $city, $tax_rate)
16+
{
17+
$query = '
18+
insert INTO `tax_zipcode` (
19+
`zipcode` ,
20+
`county` ,
21+
`city` ,
22+
`tax_rate`
23+
)
24+
VALUES (
25+
' . '\'' . $ccode . '\', \'' . $county . '\', \'' . $city . '\', ' . $tax_rate . ')
26+
ON DUPLICATE KEY UPDATE `tax_rate` = ' . $tax_rate . ';';
27+
28+
29+
$this->connection->query($query);
30+
}
31+
32+
public function delete()
33+
{
34+
$this->connection->query(
35+
' DELETE FROM table_name'
36+
);
37+
}
38+
39+
public function delete2()
40+
{
41+
42+
$this->connection->query(
43+
"
44+
DROP table table_name"
45+
);
46+
}
47+
48+
public function truncate()
49+
{
50+
$this->connection->query(
51+
'
52+
TRUNCATE table table_name'
53+
);
54+
}
55+
56+
public function runQuery($countyInfo, $countyName)
57+
{
58+
$query = '
59+
UPDATE `table_name`
60+
SET `tax_rate` = \'' . $countyInfo['tax_percentage'] . '\',
61+
`auth_code` = \'' . $countyInfo['auth_code'] . '\'
62+
WHERE county = \'' . $countyName . '\'';
63+
$this->connection->query($query);
64+
65+
$this->connection->query('CREATE TABLE Persons
66+
(
67+
PersonID int,
68+
LastName varchar(255),
69+
FirstName varchar(255),
70+
Address varchar(255),
71+
City varchar(255)
72+
);');
73+
}
74+
75+
public function getQuery($period)
76+
{
77+
$this->_period = $period;
78+
79+
$query = "
80+
select `report_data`
81+
FROM `trending_report`
82+
WHERE `created_at` <= CURDATE( )
83+
AND CURDATE( ) <= `expire_at`
84+
AND `last_for` = ' . $period . '
85+
ORDER BY `created_at` DESC
86+
LIMIT 1
87+
";
88+
89+
return $query;
90+
}
91+
}
92+
93+
$installer = $this;
94+
95+
$installer->run("
96+
ALTER TABLE `{$installer->getTable('enterprise_catalogpermissions/permission')}`
97+
CHANGE `website_id` `website_id` SMALLINT(5) UNSIGNED DEFAULT NULL,
98+
CHANGE `customer_group_id` `customer_group_id` SMALLINT(3) UNSIGNED DEFAULT NULL;
99+
");
100+
101+
$q = <<<EOT
102+
select * from table_name1
103+
EOT;
104+
105+
$q2 = <<<'EOT'
106+
select * from table_name2
107+
EOT;
108+
109+
$q3 = 'select * from table_name3';
110+
$q4 = 'Selects from database';
111+
$q5 = '<select></select>';
112+
113+
$message = 'ERROR : UPDATE SINGLE CONTACT';
114+
$message2 = 'ERROR : SELECT SINGLE CONTACT';
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/**
3+
* Copyright © Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Tests\SQL;
7+
8+
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
9+
10+
/**
11+
* Class RawQueryUnitTest
12+
*/
13+
class RawQueryUnitTest extends AbstractSniffUnitTest
14+
{
15+
/**
16+
* @inheritdoc
17+
*/
18+
public function getErrorList()
19+
{
20+
return [];
21+
}
22+
23+
/**
24+
* @inheritdoc
25+
*/
26+
public function getWarningList()
27+
{
28+
return [
29+
18 => 1,
30+
35 => 1,
31+
44 => 1,
32+
52 => 1,
33+
59 => 1,
34+
65 => 1,
35+
80 => 1,
36+
102 => 1,
37+
106 => 1,
38+
109 => 1,
39+
];
40+
}
41+
}

Magento/ruleset.xml

+4
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@
9999
<severity>9</severity>
100100
<type>warning</type>
101101
</rule>
102+
<rule ref="Magento.SQL.RawQuery">
103+
<severity>9</severity>
104+
<type>warning</type>
105+
</rule>
102106
<rule ref="Squiz.PHP.NonExecutableCode">
103107
<severity>9</severity>
104108
<type>warning</type>

0 commit comments

Comments
 (0)