/
tebo
/
BubblesCode
Обзор
Документация
Войти
/
tebo
/
BubblesCode
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
problems/safe_runner.py
65 строк
3 KB
tebo
first_commit
03 июн 2026, 15:20
03 июн 2026, 15:20
e3a5c0b
Код
Авторство
О чём код?
# problems/safe_runner.py import ast # Список модулей, которые ученику МОЖНО импортировать. Все остальное - запрещено. ALLOWED_MODULES = [ 'math', 'random', 'datetime', 'functools', 'itertools', 're', 'sys', 'collections', 'heapq', 'json' ] # Список встроенных функций, которые МОЖНО использовать. ALLOWED_BUILTINS = [ 'print', 'len', 'range', 'list', 'dict', 'set', 'tuple', 'str', 'int', 'float', 'bool', 'abs', 'max', 'min', 'sum', 'sorted', 'reversed', 'zip', 'enumerate', 'map', 'filter', 'all', 'any', 'isinstance', 'round' ] class CodeVisitor(ast.NodeVisitor): """ Класс-посетитель, который обходит дерево кода и ищет опасные узлы. """ def __init__(self): self.errors = [] def visit_Import(self, node): for alias in node.names: if alias.name not in ALLOWED_MODULES: self.errors.append(f"Импорт модуля '{alias.name}' запрещен.") self.generic_visit(node) def visit_ImportFrom(self, node): if node.module not in ALLOWED_MODULES: self.errors.append(f"Импорт из модуля '{node.module}' запрещен.") self.generic_visit(node) def visit_Call(self, node): if isinstance(node.func, ast.Name): func_name = node.func.id # Проверяем опасные встроенные функции if func_name not in ALLOWED_BUILTINS and func_name not in globals(): # Проверяем, не является ли это вызовом разрешенного класса (напр. ListNode) if func_name not in ['ListNode', 'TreeNode']: self.errors.append(f"Вызов функции '{func_name}' запрещен.") self.generic_visit(node) def visit_Attribute(self, node): # Запрещаем доступ к "приватным" атрибутам, начинающимся с _ if node.attr.startswith('_'): self.errors.append("Доступ к приватным атрибутам (начинающимся с '_') запрещен.") self.generic_visit(node) def is_safe_code(code: str) -> (bool, list): """ Проверяет код на безопасность, анализируя его AST-дерево. Возвращает кортеж: (True/False, список ошибок). """ try: tree = ast.parse(code) visitor = CodeVisitor() visitor.visit(tree) if visitor.errors: return False, visitor.errors return True, [] except SyntaxError as e: return False, [f"Синтаксическая ошибка в коде: {e}"]