Code Style Checker: started to implement checker for security related issues.

Sun, 07 Jun 2020 20:19:54 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 07 Jun 2020 20:19:54 +0200
changeset 7611
d546c4e72f52
parent 7610
df7025fe26a3
child 7612
ca1ce1e0fcff

Code Style Checker: started to implement checker for security related issues.

eric6.e4p file | annotate | diff | comparison | revisions
eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py file | annotate | diff | comparison | revisions
eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py file | annotate | diff | comparison | revisions
eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCodeSelectionDialog.py file | annotate | diff | comparison | revisions
eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleStatisticsDialog.py file | annotate | diff | comparison | revisions
eric6/Plugins/CheckerPlugins/CodeStyleChecker/translations.py file | annotate | diff | comparison | revisions
--- a/eric6.e4p	Sat Jun 06 19:42:15 2020 +0200
+++ b/eric6.e4p	Sun Jun 07 20:19:54 2020 +0200
@@ -319,6 +319,14 @@
     <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/DocStyleChecker.py</Source>
     <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py</Source>
     <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/NamingStyleChecker.py</Source>
+    <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/__init__.py</Source>
+    <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/blackListCalls.py</Source>
+    <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/SecurityChecker.py</Source>
+    <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/SecurityContext.py</Source>
+    <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/SecurityNodeVisitor.py</Source>
+    <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/SecurityUtils.py</Source>
+    <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/__init__.py</Source>
+    <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/translations.py</Source>
     <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/__init__.py</Source>
     <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/eradicate.py</Source>
     <Source>eric6/Plugins/CheckerPlugins/CodeStyleChecker/mccabe.py</Source>
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py	Sat Jun 06 19:42:15 2020 +0200
+++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py	Sun Jun 07 20:19:54 2020 +0200
@@ -24,6 +24,7 @@
 from DocStyleChecker import DocStyleChecker
 from MiscellaneousChecker import MiscellaneousChecker
 from ComplexityChecker import ComplexityChecker
+from Security.SecurityChecker import SecurityChecker
 
 
 def initService():
@@ -264,9 +265,9 @@
         excludeMessages, includeMessages, repeatMessages, fixCodes,
         noFixCodes, fixIssues, maxLineLength, maxDocLineLength, blankLines,
         hangClosing, docType, codeComplexityArgs, miscellaneousArgs,
-        annotationArgs, errors, eol, encoding, backup)
+        annotationArgs, securityArgs, errors, eol, encoding, backup)
     @type list of (str, str, bool, str, str, bool, int, list of (int, int),
-        bool, str, dict, dict, list of str, str, str, bool)
+        bool, str, dict, dict, dict, list of str, str, str, bool)
     @return tuple of statistics data and list of result dictionaries with
         keys:
         <ul>
@@ -285,8 +286,8 @@
     """
     (excludeMessages, includeMessages, repeatMessages, fixCodes, noFixCodes,
      fixIssues, maxLineLength, maxDocLineLength, blankLines, hangClosing,
-     docType, codeComplexityArgs, miscellaneousArgs, annotationArgs, errors,
-     eol, encoding, backup) = args
+     docType, codeComplexityArgs, miscellaneousArgs, annotationArgs,
+     securityArgs, errors, eol, encoding, backup) = args
     
     stats = {}
 
@@ -319,6 +320,8 @@
         else:
             ignore = []
         
+        # TODO: perform syntax check and report invalid syntax once for all
+        
         # check coding style
         pycodestyle.BLANK_LINES_CONFIG = {
             # Top level class and function.
@@ -372,6 +375,13 @@
             annotationsChecker.run()
             stats.update(annotationsChecker.counters)
             errors += annotationsChecker.errors
+        
+        securityChecker = SecurityChecker(
+            source, filename, select, ignore, [], repeatMessages,
+            securityArgs)
+        securityChecker.run()
+        stats.update(securityChecker.counters)
+        errors += securityChecker.errors
     
     errorsDict = {}
     for error in errors:
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py	Sat Jun 06 19:42:15 2020 +0200
+++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py	Sun Jun 07 20:19:54 2020 +0200
@@ -71,6 +71,9 @@
         "N": QCoreApplication.translate(
             "CheckerCategories",
             "Naming"),
+        "S": QCoreApplication.translate(
+            "CheckerCategories",
+            "Security"),
         "W": QCoreApplication.translate(
             "CheckerCategories",
             "Warnings"),
@@ -254,6 +257,18 @@
             itm.setIcon(1, UI.PixmapCache.getIcon("namingError"))
         elif result["code"].startswith("D"):
             itm.setIcon(1, UI.PixmapCache.getIcon("docstringError"))
+        elif result["code"].startswith("S"):
+            if "severity" in result:
+                if result["severity"] == "H":
+                    itm.setIcon(1, UI.PixmapCache.getIcon("securityLow"))
+                elif result["severity"] == "M":
+                    itm.setIcon(1, UI.PixmapCache.getIcon("securityMedium"))
+                elif result["severity"] == "L":
+                    itm.setIcon(1, UI.PixmapCache.getIcon("securityHigh"))
+                else:
+                    itm.setIcon(1, UI.PixmapCache.getIcon("securityLow"))
+            else:
+                itm.setIcon(1, UI.PixmapCache.getIcon("securityLow"))
         else:
             itm.setIcon(1, UI.PixmapCache.getIcon("syntaxError"))
         if result["fixed"]:
@@ -581,11 +596,14 @@
                     self.maxAnnotationsComplexitySpinBox.value(),
             }
             
+            # TODO: implement safety arguments
+            safetyArgs = {}
+            
             self.__options = [excludeMessages, includeMessages, repeatMessages,
                               fixCodes, noFixCodes, fixIssues, maxLineLength,
                               maxDocLineLength, blankLines, hangClosing,
                               docType, codeComplexityArgs, miscellaneousArgs,
-                              annotationArgs]
+                              annotationArgs, safetyArgs]
             
             # now go through all the files
             self.progress = 0
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCodeSelectionDialog.py	Sat Jun 06 19:42:15 2020 +0200
+++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCodeSelectionDialog.py	Sun Jun 07 20:19:54 2020 +0200
@@ -43,13 +43,17 @@
             codeList = [code for code in codeList if not code[0] in categories]
         
         from .translations import _messages, _messages_sample_args
+        from .Security import translations as s_translations
         
         if showFixCodes:
             from .CodeStyleFixer import FixableCodeStyleIssues
             selectableCodes = FixableCodeStyleIssues
         else:
-            selectableCodes = [x for x in list(_messages.keys())
-                               if not x.startswith('FIX')]
+            selectableCodes = (
+                [x for x in list(_messages.keys())
+                 if not x.startswith('FIX')] +
+                [x for x in list(s_translations._messages.keys())]
+            )
             if categories:
                 # filter by category
                 selectableCodes = [x for x in selectableCodes
@@ -59,6 +63,11 @@
                 message = _messages[code].format(*_messages_sample_args[code])
             elif code in _messages:
                 message = _messages[code]
+            elif code in s_translations._messages_sample_args:
+                message = s_translations._messages[code].format(
+                    *s_translations._messages_sample_args)
+            elif code in s_translations._messages:
+                message = s_translations._messages[code]
             else:
                 continue
             itm = QTreeWidgetItem(self.codeTable, [code, message])
@@ -70,6 +79,8 @@
                 itm.setIcon(0, UI.PixmapCache.getIcon("namingError"))
             elif code.startswith("D"):
                 itm.setIcon(0, UI.PixmapCache.getIcon("docstringError"))
+            elif code.startswith("S"):
+                itm.setIcon(0, UI.PixmapCache.getIcon("securityLow"))
             else:
                 # unknown category prefix => warning
                 itm.setIcon(0, UI.PixmapCache.getIcon("warning"))
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleStatisticsDialog.py	Sat Jun 06 19:42:15 2020 +0200
+++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleStatisticsDialog.py	Sun Jun 07 20:19:54 2020 +0200
@@ -13,6 +13,7 @@
 from PyQt5.QtWidgets import QDialog, QTreeWidgetItem
 
 from .translations import _messages, _messages_sample_args
+from .Security import translations as s_translations
 
 from .Ui_CodeStyleStatisticsDialog import Ui_CodeStyleStatisticsDialog
 
@@ -47,12 +48,15 @@
         totalIssues = 0
         
         for code in sorted(stats.keys()):
-            message = _messages.get(code)
+            message = _messages.get(code) or s_translations._messages.get(code)
             if message is None:
                 continue
             
             if code in _messages_sample_args:
                 message = message.format(*_messages_sample_args[code])
+            elif code in s_translations._messages_sample_args:
+                message = message.format(
+                    *s_translations._messages_sample_args[code])
             
             self.__createItem(stats[code], code, message)
             totalIssues += stats[code]
@@ -91,6 +95,8 @@
             itm.setIcon(1, UI.PixmapCache.getIcon("namingError"))
         elif code.startswith("D"):
             itm.setIcon(1, UI.PixmapCache.getIcon("docstringError"))
+        elif code.startswith("S"):
+            itm.setIcon(1, UI.PixmapCache.getIcon("securityLow"))
         
         itm.setTextAlignment(0, Qt.AlignRight)
         itm.setTextAlignment(1, Qt.AlignHCenter)
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/translations.py	Sat Jun 06 19:42:15 2020 +0200
+++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/translations.py	Sun Jun 07 20:19:54 2020 +0200
@@ -1091,12 +1091,17 @@
     @return translated and formatted message
     @rtype str
     """
-    if messageCode in _messages:
+    if messageCode.startswith("S"):
+        from .Security import translations as s_translations
+        return s_translations.getTranslatedMessage(messageCode, messageArgs)
+    
+    elif messageCode in _messages:
         if isinstance(messageArgs, int):
             # Retranslate with correct plural form
             return _messages[messageCode](messageArgs)
         else:
             return _messages[messageCode].format(*messageArgs)
+    
     else:
         return QCoreApplication.translate(
             "CodeStyleFixer", " no message defined for code '{0}'"

eric ide

mercurial