def injection_check(filename: str): """Checks whether given code file does not contain harmful code to server operation. Args: filename (str): the code file to check Raises: ARgorithmError: Raised if possible harmful code injection """ count = 0 with open(filename, 'r') as f: lines = f.readlines() for line in lines: if "import ARgorithmToolkit" in line or "from ARgorithmToolkit" in line: count += 1 if count == 0: raise ARgorithmError("ARgorithmToolkit not imported") for line in lines: if line.startswith("from"): if not re.search(r"^from\s+ARgorithmToolkit", line): raise ARgorithmError("invalid module imported") for line in lines: if line.startswith("import"): if not re.search(r"^import\s+ARgorithmToolkit", line): raise ARgorithmError("invalid module imported") text = '\n'.join(lines) file_tokens = checker.make_tokens(text) tokens = [token[1] for token in file_tokens if token[0] == 1] not_allowed = list(set(tokens) & set(FORBIDDEN)) if len(not_allowed) > 0: raise ARgorithmError('possible code injection')
def flakes(self, input, *expectedOutputs, **kw): tree = ast.parse(textwrap.dedent(input)) file_tokens = checker.make_tokens(textwrap.dedent(input)) if kw.get("is_segment"): tree = tree.body[0] kw.pop("is_segment") w = checker.Checker( tree, file_tokens=file_tokens, withDoctest=self.withDoctest, **kw ) outputs = [type(o) for o in w.messages] expectedOutputs = list(expectedOutputs) outputs.sort(key=lambda t: t.__name__) expectedOutputs.sort(key=lambda t: t.__name__) self.assertEqual( outputs, expectedOutputs, """\ for input: %s expected outputs: %r but got: %s""" % (input, expectedOutputs, "\n".join([str(o) for o in w.messages])), ) return w
def check(codeString, filename, reporter=None): """ Check the Python source given by C{codeString} for flakes. @param codeString: The Python source to check. @type codeString: C{str} @param filename: The name of the file the source came from, used to report errors. @type filename: C{str} @param reporter: A L{Reporter} instance, where errors and warnings will be reported. @return: The number of warnings emitted. @rtype: C{int} """ if reporter is None: reporter = modReporter._makeDefaultReporter() # First, compile into an AST and handle syntax errors. try: tree = ast.parse(codeString, filename=filename) except SyntaxError: value = sys.exc_info()[1] msg = value.args[0] (lineno, offset, text) = value.lineno, value.offset, value.text if checker.PYPY: if text is None: lines = codeString.splitlines() if len(lines) >= lineno: text = lines[lineno - 1] if sys.version_info >= (3, ) and isinstance(text, bytes): try: text = text.decode('ascii') except UnicodeDecodeError: text = None offset -= 1 # If there's an encoding problem with the file, the text is None. if text is None: # Avoid using msg, since for the only known case, it contains a # bogus message that claims the encoding the file declared was # unknown. reporter.unexpectedError(filename, 'problem decoding source') else: reporter.syntaxError(filename, msg, lineno, offset, text) return 1 except Exception: reporter.unexpectedError(filename, 'problem decoding source') return 1 # Okay, it's syntactically valid. Now check it. file_tokens = checker.make_tokens(codeString) w = checker.Checker(tree, file_tokens=file_tokens, filename=filename) w.messages.sort(key=lambda m: m.lineno) for warning in w.messages: reporter.flake(warning) return len(w.messages)
def _collect(s): """ Run L{_collect_type_comments} on the parsed source and return the mapping from nodes to comments. The return value is converted to a set: {(node_type, tuple of comments), ...} """ tree = ast.parse(s) tokens = checker.make_tokens(s) ret = checker._collect_type_comments(tree, tokens) return {(type(k), tuple(s for _, s in v)) for k, v in ret.items()}
def test_impossibleContext(self): """ A Name node with an unrecognized context results in a RuntimeError being raised. """ tree = ast.parse("x = 10") file_tokens = checker.make_tokens("x = 10") # Make it into something unrecognizable. tree.body[0].targets[0].ctx = object() self.assertRaises(RuntimeError, checker.Checker, tree, file_tokens=file_tokens)
def test_impossibleContext(self): """ A Name node with an unrecognized context results in a RuntimeError being raised. """ tree = ast.parse("x = 10") tokens = checker.make_tokens("x = 10") # Make it into something unrecognizable. tree.body[0].targets[0].ctx = object() self.assertRaises(RuntimeError, checker.Checker, tree, tokens=tokens)
def flakes(self, input, *expectedOutputs, **kw): tree = ast.parse(textwrap.dedent(input)) file_tokens = checker.make_tokens(textwrap.dedent(input)) if kw.get('is_segment'): tree = tree.body[0] kw.pop('is_segment') w = checker.Checker( tree, file_tokens=file_tokens, withDoctest=self.withDoctest, **kw ) outputs = [type(o) for o in w.messages] expectedOutputs = list(expectedOutputs) outputs.sort(key=lambda t: t.__name__) expectedOutputs.sort(key=lambda t: t.__name__) self.assertEqual(outputs, expectedOutputs, '''\ for input: %s expected outputs: %r but got: %s''' % (input, expectedOutputs, '\n'.join([str(o) for o in w.messages]))) return w
def to_output(self): """ Produce json output :return: json result report """ results = [] cli = {'cli': results} warning_dict = {} try: tree = ast.parse(self.codeString, filename=self.filename) file_tokens = checker.make_tokens(self.codeString) w = checker.Checker(tree, file_tokens=file_tokens, filename=self.filename) w.messages.sort(key=lambda m: m.lineno) for warning in w.messages: warning_dict['message'] = str(warning).split(' ', 1)[1] warning = str(warning).split(' ', 1)[0] loc = str(warning).split(':') warning_dict['file'] = loc[0] if loc[0] else None warning_dict['line'] = loc[1] if loc[1] else None warning_dict['column'] = loc[2] if loc[2] else None results.append(warning_dict.copy()) except SyntaxError: value = sys.exc_info()[1] msg = value.args[0] warning_dict['message'] = msg warning_dict['file'] = self.filename warning_dict['line'] = value.lineno if value.lineno else None warning_dict['column'] = value.offset if value.offset else None results.append(warning_dict.copy()) flakes_json = {'results': cli} flakes_json = json.dumps(flakes_json, sort_keys=True, indent=2, separators=(',', ': ')) return flakes_json + '\n'