[FIX] adding a standalone test for markup
This commits make a new standalone test for Markup()
The idea is to only flag the usage of Markup inside of runbot if
it is called on the non-constant string.
Markup('<span> %s </span>') % text #should not raise a flag,
Markup('<span> %s </span>' % 'text') #should raise a flag
closes odoo/odoo#131206
Signed-off-by: Vranckx Florian (flvr) <flvr@odoo.com>
Co-authored-by: Alex Roscav <roal@odoo.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
from typing import Optional
|
||||
|
||||
import astroid
|
||||
from pylint import interfaces, checkers
|
||||
|
||||
try:
|
||||
from pylint.checkers.utils import only_required_for_messages
|
||||
except ImportError:
|
||||
from pylint.checkers.utils import check_messages as only_required_for_messages
|
||||
|
||||
|
||||
class OdooBaseChecker(checkers.BaseChecker):
|
||||
__implements__ = interfaces.IAstroidChecker
|
||||
name = 'odoo'
|
||||
|
||||
msgs = {
|
||||
'E8504': (
|
||||
'The Markup constructor called with a non-constant argument',
|
||||
'non-const-markup',
|
||||
'',
|
||||
)
|
||||
}
|
||||
|
||||
@only_required_for_messages('non-const-markup')
|
||||
def visit_call(self, node):
|
||||
if (isinstance(node.func, astroid.Name) and
|
||||
node.func.name == "Markup" and
|
||||
not self._is_constant(node.args[0])):
|
||||
self.add_message('non-const-markup', node=node, col_offset=len(node.as_string().split('\\n')))
|
||||
elif (isinstance(node.func, astroid.Attribute) and
|
||||
node.func.attrname == "Markup" and
|
||||
not self._is_constant(node.args[0])):
|
||||
self.add_message('non-const-markup', node=node, col_offset=len(node.as_string().split('\\n')))
|
||||
|
||||
def _is_constant(self, node: Optional[astroid.node_classes.NodeNG]) -> bool:
|
||||
if isinstance(node, astroid.Const) or node is None:
|
||||
return True
|
||||
elif isinstance(node, astroid.JoinedStr):
|
||||
return all(map(self._is_constant, node.values))
|
||||
elif isinstance(node, astroid.FormattedValue):
|
||||
return self._is_constant(node.value)
|
||||
elif isinstance(node, astroid.Name):
|
||||
_, assignments = node.lookup(node.name)
|
||||
return all(map(self._is_constant, assignments))
|
||||
elif isinstance(node, astroid.AssignName):
|
||||
return self._is_constant(node.parent)
|
||||
elif isinstance(node, astroid.Assign):
|
||||
return self._is_constant(node.value)
|
||||
elif (isinstance(node, astroid.Call) and
|
||||
isinstance(node.func, astroid.Attribute) and
|
||||
node.func.attrname in ["format", "join"]):
|
||||
return (self._is_constant(node.func.expr) and
|
||||
all(map(self._is_constant, node.args)) and
|
||||
all(map(self._is_constant, node.keywords)))
|
||||
elif isinstance(node, astroid.Keyword):
|
||||
return self._is_constant(node.value)
|
||||
elif isinstance(node, (astroid.List, astroid.Set, astroid.Tuple)):
|
||||
return all(map(self._is_constant, node.elts))
|
||||
elif isinstance(node, astroid.Dict):
|
||||
return all(map(self._is_constant, node.values))
|
||||
elif isinstance(node, astroid.BinOp):
|
||||
return self._is_constant(node.left) and self._is_constant(node.right)
|
||||
elif isinstance(node, astroid.IfExp):
|
||||
return self._is_constant(node.body) and self._is_constant(node.orelse)
|
||||
return False
|
||||
|
||||
def register(linter):
|
||||
linter.register_checker(OdooBaseChecker(linter))
|
||||
@@ -0,0 +1,18 @@
|
||||
from os import environ, path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
#This test is meant to be standalone, correct usage : python test_security.py file1 file2 file3 ...
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
HERE = path.dirname(__file__)
|
||||
|
||||
if 'PYTHONPATH' not in environ:
|
||||
environ['PYTHONPATH'] = HERE
|
||||
else:
|
||||
environ['PYTHONPATH'] += ':' + HERE
|
||||
|
||||
command = ['pylint', '--rcfile=/dev/null', '--disable=all', '--output-format', 'json', '--enable=non-const-markup', '--reports=n', '--load-plugins=_odoo_checker_markup', *sys.argv[1:]]
|
||||
|
||||
proc = subprocess.run(command, env=environ, check=True)
|
||||
Reference in New Issue
Block a user