diff -r 321555d0303b -r d1c6608155ef src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Security/SecurityUtils.py --- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Security/SecurityUtils.py Tue Jan 16 14:35:46 2024 +0100 +++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Security/SecurityUtils.py Tue Jan 16 18:24:06 2024 +0100 @@ -183,6 +183,33 @@ return obj +def calcLineRange(node): + """ + Function to calculate the line range for a subtree. + + @param node node to calculate the line range for + @type ast.AST + @return tuple containing the start and end line of the subtree + @rtype tuple of (int, int) + """ + if hasattr(node, "_securityLineRange"): + return node._securityLineRange + + lines_min = 9999999999 + lines_max = -1 + if hasattr(node, "lineno"): + lines_min = node.lineno + lines_max = node.lineno + for n in ast.iter_child_nodes(node): + lines_minmax = calcLineRange(n) + lines_min = min(lines_min, lines_minmax[0]) + lines_max = max(lines_max, lines_minmax[1]) + + node._securityLineRange = (lines_min, lines_max) + + return (lines_min, lines_max) + + def linerange(node): """ Function to get line number range from a node. @@ -192,48 +219,55 @@ @return list containing the line number range @rtype list of int """ - strip = {"body": None, "orelse": None, "handlers": None, "finalbody": None} - for key in strip: - if hasattr(node, key): - strip[key] = getattr(node, key) - node.key = [] + if hasattr(node, "lineno") and hasattr(node, "end_lineno"): + return list(range(node.lineno, node.end_lineno + 1)) + else: + if hasattr(node, "_securityLineRangeStripped"): + lines_minmax = node._securityLineRangeStripped + return list(range(lines_minmax[0], lines_minmax[1] + 1)) - lines_min = 9999999999 - lines_max = -1 - for n in ast.walk(node): - if hasattr(n, "lineno"): - lines_min = min(lines_min, n.lineno) - lines_max = max(lines_max, n.lineno) - - for key in strip: - if strip[key] is not None: - node.key = strip[key] - - if lines_max > -1: - return list(range(lines_min, lines_max + 1)) + strip = { + "body": None, + "orelse": None, + "handlers": None, + "finalbody": None, + } + for key in strip: + if hasattr(node, key): + strip[key] = getattr(node, key) + setattr(node, key, []) - return [0, 1] - + lines_min = 9999999999 + lines_max = -1 + if hasattr(node, "lineno"): + lines_min = node.lineno + lines_max = node.lineno + for n in ast.iter_child_nodes(node): + lines_minmax = calcLineRange(n) + lines_min = min(lines_min, lines_minmax[0]) + lines_max = max(lines_max, lines_minmax[1]) -def linerange_fix(node): - """ - Function to get a line number range working around a known Python bug - with multi-line strings. + for key in strip: + if strip[key] is not None: + setattr(node, key, strip[key]) - @param node node to extract a line range from - @type ast.AST - @return list containing the line number range - @rtype list of int - """ - # deal with multiline strings lineno behavior (Python issue #16806) - lines = linerange(node) - if hasattr(node, "_securitySibling") and hasattr(node._securitySibling, "lineno"): - start = min(lines) - delta = node._securitySibling.lineno - start - if delta > 1: - return list(range(start, node._securitySibling.lineno)) + if lines_max == -1: + lines_min = 0 + lines_max = 1 + + node._securityLineRangeStripped = (lines_min, lines_max) - return lines + lines = list(range(lines_min, lines_max + 1)) + # deal with multi-line strings lineno behavior (Python issue #16806) + if hasattr(node, "_securitySibling") and hasattr( + node._securitySibling, "lineno" + ): + start = min(lines) + delta = node._securitySibling.lineno - start + if delta > 1: + return list(range(start, node._securitySibling.lineno)) + + return lines def escapedBytesRepresentation(b):