#! /usr/bin/env python3
# -*- coding: utf-8 -*-
#
# calculette vaguement similaire à "calc" ("apcalc" http://www.isthe.com/chongo/tech/comp/calc/) sous linux.
#
# https://stackoverflow.com/questions/64618043/safely-using-eval-to-calculate-using-the-math-module-in-python
# ne prévient pas ce genre de code:
#   > calc.py "().__class__.__base__.__subclasses__()[-1].__init__.__globals__['__builtins__']['__import__']('os').system('dir')"
#   ...exécute "dir"... ou pire
#   => on vérifie la chaine avant l'exécution
#
# exemple:
#   > calc.py 2*sin(pi/4)/sqrt(3)
#   0.8164965809277261

import sys
import math

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print('usage:\n\tsys.argv[0] math_expression')
        sys.exit(1)
    expr = sys.argv[1]
    # teste la chaine à exécuter
    for forbidden in ['_', '[', ']']:
        if forbidden in expr:
            print(f'character {repr(forbidden)} not allowed!')
            sys.exit(1)
    # crée un espace de noms local contenant les fonctions mathématiques (et uniquement celles-là)
    mathok = {k: v for k, v in math.__dict__.items() if not k.startswith("__")}
    # évalue dans un environnement vaguement sécurisé
    print(eval(sys.argv[1], {"__builtins__": {}}, mathok))

@@ -589,16 +589,20 @@
 port sys
+, os
 %0Aimport 
@@ -675,16 +675,17 @@
   print(
+f
 'usage:%5C
@@ -687,16 +687,34 @@
 age:%5Cn%5Ct
+%7Bos.path.basename(
 sys.argv
@@ -716,17 +716,20 @@
 .argv%5B0%5D
- 
+)%7D %3C
 math_exp
@@ -735,16 +735,17 @@
 pression
+%3E
 ')%0A     

fix help