#!/usr/bin/env python3 import sys import io import os import math as _math import json as _json import re as _re import random as _random import collections as _collections import itertools as _itertools import functools as _functools import operator as _operator import string as _string import decimal as _decimal import fractions as _fractions import statistics as _statistics import heapq as _heapq import bisect as _bisect import copy as _copy import typing as _typing import textwrap as _textwrap import datetime as _datetime import hashlib as _hashlib import uuid as _uuid import secrets as _secrets import enum as _enum import base64 as _base64 import time as _time _SAFE_MODULES = { 'math': _math, 'json': _json, 're': _re, 'random': _random, 'collections': _collections, 'itertools': _itertools, 'functools': _functools, 'operator': _operator, 'string': _string, 'decimal': _decimal, 'fractions': _fractions, 'statistics': _statistics, 'heapq': _heapq, 'bisect': _bisect, 'copy': _copy, 'typing': _typing, 'textwrap': _textwrap, 'datetime': _datetime, 'hashlib': _hashlib, 'uuid': _uuid, 'secrets': _secrets, 'enum': _enum, 'base64': _base64, 'time': _time, } _ALLOWED_READ_DIRS = {os.path.realpath(p) for p in ('/tmp', os.getcwd()) if os.path.isdir(p)} def _safe_import(name, *args, **kwargs): if name in _SAFE_MODULES: return _SAFE_MODULES[name] raise ImportError(f"Module '{name}' is not allowed in sandbox") def _safe_open(file, mode='r', *args, **kwargs): if 'w' in mode or 'a' in mode or '+' in mode or 'x' in mode: raise PermissionError("File writing is not allowed in sandbox") real = os.path.realpath(os.path.abspath(str(file))) allowed = False for d in _ALLOWED_READ_DIRS: if real.startswith(d + os.sep) or real == d: allowed = True break if not allowed: raise PermissionError(f"File '{file}' is outside allowed read directories") if 'b' in mode: return io.open(file, mode, *args, **kwargs) return io.open(file, mode, *args, **kwargs) def _safe_getattr(obj, name, *args): if isinstance(obj, (type, object)) and name in ('__class__', '__bases__', '__subclasses__', '__mro__', '__globals__', '__code__', '__closure__', '__dict__', '__builtins__'): raise AttributeError(f"Access to '{name}' is not allowed in sandbox") if args: return getattr(obj, name, args[0]) return getattr(obj, name) def _safe_setattr(obj, name, value): if name.startswith('_'): raise AttributeError(f"Setting attribute '{name}' is not allowed in sandbox") setattr(obj, name, value) def _safe_delattr(obj, name): if name.startswith('_'): raise AttributeError(f"Deleting attribute '{name}' is not allowed in sandbox") delattr(obj, name) _SAFE_BUILTINS = { '__import__': _safe_import, 'print': print, 'len': len, 'range': range, 'int': int, 'float': float, 'str': str, 'bool': bool, 'list': list, 'dict': dict, 'tuple': tuple, 'set': set, 'frozenset': frozenset, 'bytes': bytes, 'bytearray': bytearray, 'True': True, 'False': False, 'None': None, 'abs': abs, 'min': min, 'max': max, 'sum': sum, 'pow': pow, 'round': round, 'divmod': divmod, 'enumerate': enumerate, 'filter': filter, 'map': map, 'zip': zip, 'all': all, 'any': any, 'iter': iter, 'next': next, 'reversed': reversed, 'sorted': sorted, 'slice': slice, 'bin': bin, 'chr': chr, 'hex': hex, 'oct': oct, 'ord': ord, 'repr': repr, 'format': format, 'hash': hash, 'id': id, 'type': type, 'isinstance': isinstance, 'issubclass': issubclass, 'hasattr': hasattr, 'getattr': _safe_getattr, 'setattr': _safe_setattr, 'delattr': _safe_delattr, 'callable': callable, 'staticmethod': staticmethod, 'classmethod': classmethod, 'property': property, 'object': object, 'super': super, 'Exception': Exception, 'ValueError': ValueError, 'TypeError': TypeError, 'KeyError': KeyError, 'IndexError': IndexError, 'AttributeError': AttributeError, 'StopIteration': StopIteration, 'RuntimeError': RuntimeError, 'ZeroDivisionError': ZeroDivisionError, 'ArithmeticError': ArithmeticError, 'EOFError': EOFError, 'NameError': NameError, 'MemoryError': MemoryError, 'NotImplementedError': NotImplementedError, 'OverflowError': OverflowError, 'RecursionError': RecursionError, 'AssertionError': AssertionError, 'ImportError': ImportError, 'PermissionError': PermissionError, 'LookupError': LookupError, 'FileNotFoundError': FileNotFoundError, 'input': input, 'open': _safe_open, } _FROZEN_ERR = TypeError("Cannot modify sandbox builtins") class _FrozenDict(dict): def __setitem__(self, key, value): raise _FROZEN_ERR def __delitem__(self, key): raise _FROZEN_ERR def pop(self, key, *args): raise _FROZEN_ERR def popitem(self): raise _FROZEN_ERR def clear(self): raise _FROZEN_ERR def update(self, *args, **kwargs): raise _FROZEN_ERR def setdefault(self, key, *args): raise _FROZEN_ERR def execute_code(code: str) -> None: try: compiled = compile(code, '', 'exec') globs = {'__builtins__': _FrozenDict(_SAFE_BUILTINS)} exec(compiled, globs) except Exception as e: print(str(e), file=sys.stderr) sys.exit(1) if __name__ == '__main__': if len(sys.argv) > 1: with open(sys.argv[1], 'r') as f: code = f.read() execute_code(code) else: code = sys.stdin.read() execute_code(code)