Hello community, here is the log from the commit of package python-simpleeval for openSUSE:Factory checked in at 2020-03-10 12:33:50 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-simpleeval (Old) and /work/SRC/openSUSE:Factory/.python-simpleeval.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-simpleeval" Tue Mar 10 12:33:50 2020 rev:4 rq:783300 version:0.9.10 Changes: -------- --- /work/SRC/openSUSE:Factory/python-simpleeval/python-simpleeval.changes 2019-04-30 13:03:51.526071253 +0200 +++ /work/SRC/openSUSE:Factory/.python-simpleeval.new.26092/python-simpleeval.changes 2020-03-10 12:33:57.336847596 +0100 @@ -1,0 +2,13 @@ +Tue Mar 10 10:40:40 UTC 2020 - Tomáš Chvátal <[email protected]> + +- Update to 0.9.10: + * minor fixes + * support for python 3.8 + +------------------------------------------------------------------- +Fri Oct 4 08:47:40 UTC 2019 - Tomáš Chvátal <[email protected]> + +- Run fdupes +- Remove not really needed commands from build + +------------------------------------------------------------------- Old: ---- LICENCE simpleeval-0.9.8.tar.gz New: ---- simpleeval-0.9.10.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-simpleeval.spec ++++++ --- /var/tmp/diff_new_pack.o5gFqG/_old 2020-03-10 12:33:59.480848651 +0100 +++ /var/tmp/diff_new_pack.o5gFqG/_new 2020-03-10 12:33:59.484848652 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-simpleeval # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # Copyright (c) 2015 Dr. Axel Braun # # All modifications and additions to the file contributed by third parties @@ -20,16 +20,14 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define modname simpleeval Name: python-%{modname} -Version: 0.9.8 +Version: 0.9.10 Release: 0 Summary: A simple, safe single expression evaluator library License: MIT -Group: Development/Languages/Python URL: https://github.com/danthedeckie/simpleeval Source0: https://files.pythonhosted.org/packages/source/s/simpleeval/%{modname}-%{version}.tar.gz -# https://github.com/danthedeckie/simpleeval/issues/55 -Source1: https://raw.githubusercontent.com/danthedeckie/simpleeval/master/LICENCE BuildRequires: %{python_module setuptools} +BuildRequires: fdupes BuildRequires: python-rpm-macros BuildArch: noarch # SECTION test requirements @@ -48,16 +46,13 @@ %prep %setup -q -n %{modname}-%{version} -rm -f %{modname}.egg-info/*.orig -cp %{SOURCE1} . %build %python_build %install %python_install -rm -rf %{buildroot}%{python_sitelib}/%{mod2nam}/tests # Don't install tests -rm -rf %{buildroot}%{python_sitelib}/%{mod2nam}/*.exe # Remove unneeded files +%python_expand %fdupes %{buildroot}%{$python_sitelib} %check %pytest ++++++ simpleeval-0.9.8.tar.gz -> simpleeval-0.9.10.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simpleeval-0.9.8/LICENCE new/simpleeval-0.9.10/LICENCE --- old/simpleeval-0.9.8/LICENCE 1970-01-01 01:00:00.000000000 +0100 +++ new/simpleeval-0.9.10/LICENCE 2017-05-03 20:39:11.000000000 +0200 @@ -0,0 +1,21 @@ +simpleeval - Copyright (c) 2013-2017 Daniel Fairhead + +(MIT Licence) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simpleeval-0.9.8/MANIFEST.in new/simpleeval-0.9.10/MANIFEST.in --- old/simpleeval-0.9.8/MANIFEST.in 2017-05-03 20:39:11.000000000 +0200 +++ new/simpleeval-0.9.10/MANIFEST.in 2019-06-18 11:27:01.000000000 +0200 @@ -1,2 +1,3 @@ include README.rst +include LICENCE include test_simpleeval.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simpleeval-0.9.8/PKG-INFO new/simpleeval-0.9.10/PKG-INFO --- old/simpleeval-0.9.8/PKG-INFO 2018-10-19 03:36:58.000000000 +0200 +++ new/simpleeval-0.9.10/PKG-INFO 2019-11-29 22:34:39.000000000 +0100 @@ -1,12 +1,12 @@ Metadata-Version: 2.1 Name: simpleeval -Version: 0.9.8 +Version: 0.9.10 Summary: A simple, safe single expression evaluator library. Home-page: https://github.com/danthedeckie/simpleeval Author: Daniel Fairhead Author-email: [email protected] License: UNKNOWN -Download-URL: https://github.com/danthedeckie/simpleeval/tarball/0.9.8 +Download-URL: https://github.com/danthedeckie/simpleeval/tarball/0.9.10 Description: simpleeval (Simple Eval) ======================== @@ -377,6 +377,10 @@ If you really need that (BE CAREFUL!), then modify the module global ``simpleeval.DISALLOW_PREFIXES``. + A few builtin functions are listed in ``simpleeval.DISALLOW_FUNCTIONS``. ``type``, ``open``, etc. + If you need to give access to this kind of functionality to your expressions, then be very + careful. You'd be better wrapping the functions in your own safe wrappers. + The initial idea came from J.F. Sebastian on Stack Overflow ( http://stackoverflow.com/a/9558001/1973500 ) with modifications and many improvements, see the head of the main file for contributors list. @@ -398,6 +402,13 @@ (requires ``entr``) + BEWARE + ------ + + I've done the best I can with this library - but there's no warrenty, no guarentee, nada. A lot of + very clever people think the whole idea of trying to sandbox CPython is impossible. Read the code + yourself, and use it at your own risk. + Keywords: eval,simple,expression,parse,ast Platform: UNKNOWN Classifier: Development Status :: 4 - Beta diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simpleeval-0.9.8/README.rst new/simpleeval-0.9.10/README.rst --- old/simpleeval-0.9.8/README.rst 2018-10-19 03:20:08.000000000 +0200 +++ new/simpleeval-0.9.10/README.rst 2019-06-18 11:26:39.000000000 +0200 @@ -368,6 +368,10 @@ If you really need that (BE CAREFUL!), then modify the module global ``simpleeval.DISALLOW_PREFIXES``. +A few builtin functions are listed in ``simpleeval.DISALLOW_FUNCTIONS``. ``type``, ``open``, etc. +If you need to give access to this kind of functionality to your expressions, then be very +careful. You'd be better wrapping the functions in your own safe wrappers. + The initial idea came from J.F. Sebastian on Stack Overflow ( http://stackoverflow.com/a/9558001/1973500 ) with modifications and many improvements, see the head of the main file for contributors list. @@ -388,3 +392,10 @@ $ make autotest (requires ``entr``) + +BEWARE +------ + +I've done the best I can with this library - but there's no warrenty, no guarentee, nada. A lot of +very clever people think the whole idea of trying to sandbox CPython is impossible. Read the code +yourself, and use it at your own risk. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simpleeval-0.9.8/setup.py new/simpleeval-0.9.10/setup.py --- old/simpleeval-0.9.8/setup.py 2018-10-19 03:22:58.000000000 +0200 +++ new/simpleeval-0.9.10/setup.py 2019-11-29 22:31:24.000000000 +0100 @@ -1,6 +1,6 @@ from setuptools import setup -__version__ = '0.9.8' +__version__ = '0.9.10' setup( name='simpleeval', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simpleeval-0.9.8/simpleeval.egg-info/PKG-INFO new/simpleeval-0.9.10/simpleeval.egg-info/PKG-INFO --- old/simpleeval-0.9.8/simpleeval.egg-info/PKG-INFO 2018-10-19 03:36:57.000000000 +0200 +++ new/simpleeval-0.9.10/simpleeval.egg-info/PKG-INFO 2019-11-29 22:34:39.000000000 +0100 @@ -1,12 +1,12 @@ Metadata-Version: 2.1 Name: simpleeval -Version: 0.9.8 +Version: 0.9.10 Summary: A simple, safe single expression evaluator library. Home-page: https://github.com/danthedeckie/simpleeval Author: Daniel Fairhead Author-email: [email protected] License: UNKNOWN -Download-URL: https://github.com/danthedeckie/simpleeval/tarball/0.9.8 +Download-URL: https://github.com/danthedeckie/simpleeval/tarball/0.9.10 Description: simpleeval (Simple Eval) ======================== @@ -377,6 +377,10 @@ If you really need that (BE CAREFUL!), then modify the module global ``simpleeval.DISALLOW_PREFIXES``. + A few builtin functions are listed in ``simpleeval.DISALLOW_FUNCTIONS``. ``type``, ``open``, etc. + If you need to give access to this kind of functionality to your expressions, then be very + careful. You'd be better wrapping the functions in your own safe wrappers. + The initial idea came from J.F. Sebastian on Stack Overflow ( http://stackoverflow.com/a/9558001/1973500 ) with modifications and many improvements, see the head of the main file for contributors list. @@ -398,6 +402,13 @@ (requires ``entr``) + BEWARE + ------ + + I've done the best I can with this library - but there's no warrenty, no guarentee, nada. A lot of + very clever people think the whole idea of trying to sandbox CPython is impossible. Read the code + yourself, and use it at your own risk. + Keywords: eval,simple,expression,parse,ast Platform: UNKNOWN Classifier: Development Status :: 4 - Beta diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simpleeval-0.9.8/simpleeval.egg-info/SOURCES.txt new/simpleeval-0.9.10/simpleeval.egg-info/SOURCES.txt --- old/simpleeval-0.9.8/simpleeval.egg-info/SOURCES.txt 2018-10-19 03:36:57.000000000 +0200 +++ new/simpleeval-0.9.10/simpleeval.egg-info/SOURCES.txt 2019-11-29 22:34:39.000000000 +0100 @@ -1,3 +1,4 @@ +LICENCE MANIFEST.in README.rst setup.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simpleeval-0.9.8/simpleeval.py new/simpleeval-0.9.10/simpleeval.py --- old/simpleeval-0.9.8/simpleeval.py 2018-10-18 04:38:58.000000000 +0200 +++ new/simpleeval-0.9.10/simpleeval.py 2019-11-29 22:30:52.000000000 +0100 @@ -1,5 +1,5 @@ """ -SimpleEval - (C) 2013-2018 Daniel Fairhead +SimpleEval - (C) 2013-2019 Daniel Fairhead ------------------------------------- An short, easy to use, safe and reasonably extensible expression evaluator. @@ -46,10 +46,11 @@ - xaled (Khalid Grandi) method chaining correctly, double-eval bugfix. - EdwardBetts (Edward Betts) spelling correction. - charlax (Charles-Axel Dein charlax) Makefile and cleanups -- mommothazaz123 (Andrew Zhu) f"string" support +- mommothazaz123 (Andrew Zhu) f"string" support, Python 3.8 support - lubieowoce (Uryga) various potential vulnerabilities - JCavallo (Jean Cavallo) names dict shouldn't be modified - +- Birne94 (Daniel Birnstiel) for fixing leaking generators. +- patricksurry (Patrick Surry) or should return last value, even if falsy. ------------------------------------- Basic Usage: @@ -94,6 +95,8 @@ import sys from random import random +PYTHON3 = sys.version_info[0] == 3 + ######################################## # Module wide 'globals' @@ -101,9 +104,19 @@ MAX_COMPREHENSION_LENGTH = 10000 MAX_POWER = 4000000 # highest exponent DISALLOW_PREFIXES = ['_', 'func_'] -DISALLOW_METHODS = ['format', 'mro'] +DISALLOW_METHODS = ['format', 'format_map', 'mro'] -PYTHON3 = sys.version_info[0] == 3 +# Disallow functions: +# This, strictly speaking, is not necessary. These /should/ never be accessable anyway, +# if DISALLOW_PREFIXES and DISALLOW_METHODS are all right. This is here to try and help +# people not be stupid. Allowing these functions opens up all sorts of holes - if any of +# their functionality is required, then please wrap them up in a safe container. And think +# very hard about it first. And don't say I didn't warn you. + +DISALLOW_FUNCTIONS = {type, isinstance, eval, getattr, setattr, help, repr, compile, open} + +if PYTHON3: + exec('DISALLOW_FUNCTIONS.add(exec)') # exec is not a function in Python2... ######################################## @@ -256,11 +269,11 @@ functions (add, random, get_val, whatever) and names. """ if not operators: - operators = DEFAULT_OPERATORS + operators = DEFAULT_OPERATORS.copy() if not functions: - functions = DEFAULT_FUNCTIONS + functions = DEFAULT_FUNCTIONS.copy() if not names: - names = DEFAULT_NAMES + names = DEFAULT_NAMES.copy() self.operators = operators self.functions = functions @@ -285,16 +298,26 @@ # py3k stuff: if hasattr(ast, 'NameConstant'): - self.nodes[ast.NameConstant] = self._eval_nameconstant + self.nodes[ast.NameConstant] = self._eval_constant # py3.6, f-strings if hasattr(ast, 'JoinedStr'): self.nodes[ast.JoinedStr] = self._eval_joinedstr # f-string self.nodes[ast.FormattedValue] = self._eval_formattedvalue # formatted value in f-string + # py3.8 uses ast.Constant instead of ast.Num, ast.Str, ast.NameConstant + if hasattr(ast, 'Constant'): + self.nodes[ast.Constant] = self._eval_constant + # Defaults: self.ATTR_INDEX_FALLBACK = ATTR_INDEX_FALLBACK + + # Check for forbidden functions: + + for f in self.functions.values(): + if f in DISALLOW_FUNCTIONS: + raise FeatureNotAvailable('This function {} is a really bad idea.'.format(f)) def eval(self, expr): @@ -332,7 +355,10 @@ return node.s @staticmethod - def _eval_nameconstant(node): + def _eval_constant(node): + if hasattr(node.value, '__len__') and len(node.value) > MAX_STRING_LENGTH: + raise IterableTooLong("Literal in statement is too long!" + " ({0}, when {1} is max)".format(len(node.value), MAX_STRING_LENGTH)) return node.value def _eval_unaryop(self, node): @@ -348,14 +374,14 @@ for value in node.values: vout = self._eval(value) if not vout: - return False + return vout return vout elif isinstance(node.op, ast.Or): for value in node.values: vout = self._eval(value) if vout: return vout - return False + return vout def _eval_compare(self, node): right = self._eval(node.left) @@ -383,6 +409,9 @@ except AttributeError as e: raise FeatureNotAvailable('Lambda Functions not implemented') + if func in DISALLOW_FUNCTIONS: + raise FeatureNotAvailable('This function is forbidden') + return func( *(self._eval(a) for a in node.args), **dict(self._eval(k) for k in node.keywords) @@ -564,9 +593,10 @@ else: to_return.append(self._eval(node.elt)) - do_generator() - - self.nodes.update({ast.Name: previous_name_evaller}) + try: + do_generator() + finally: + self.nodes.update({ast.Name: previous_name_evaller}) return to_return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/simpleeval-0.9.8/test_simpleeval.py new/simpleeval-0.9.10/test_simpleeval.py --- old/simpleeval-0.9.8/test_simpleeval.py 2018-10-18 04:41:16.000000000 +0200 +++ new/simpleeval-0.9.10/test_simpleeval.py 2019-11-29 22:30:52.000000000 +0100 @@ -46,6 +46,7 @@ self.t("100 % 9", 1) def test_bools_and_or(self): + self.t('True and ""', "") self.t('True and False', False) self.t('True or False', True) self.t('False or False', False) @@ -55,6 +56,9 @@ self.t('110 != 100 + 10 and True', False) self.t('False or 42', 42) + self.t('False or None', None) + self.t('None or None', None) + self.s.names = {'out': True, 'position': 3} self.t('(out and position <=6 and -10)' ' or (out and position > 6 and -5)' @@ -208,10 +212,12 @@ def test_randoms(self): """ test the rand() and randint() functions """ - self.s.functions['type'] = type + i = self.s.eval('randint(1000)') + self.assertEqual(type(i), int) + self.assertLessEqual(i, 1000) - self.t('type(randint(1000))', int) - self.t('type(rand())', float) + f = self.s.eval('rand()') + self.assertEqual(type(f), float) self.t("randint(20)<20", True) self.t("rand()<1.0", True) @@ -437,6 +443,10 @@ with self.assertRaises(simpleeval.FeatureNotAvailable): self.t('"{string.__class__}".format(string="things")', 0) + with self.assertRaises(simpleeval.FeatureNotAvailable): + self.s.names['x'] = {"a": 1} + self.t('"{a.__class__}".format_map(x)', 0) + if sys.version_info >= (3, 6, 0): self.s.names['x'] = 42 @@ -633,6 +643,15 @@ with self.assertRaises(simpleeval.IterableTooLong): self.s.eval(s) + def test_no_leaking_names(self): + # see issue #52, failing list comprehensions could leak locals + with self.assertRaises(simpleeval.NameNotDefined): + self.s.eval('[x if x == "2" else y for x in "123"]') + + with self.assertRaises(simpleeval.NameNotDefined): + self.s.eval('x') + + class TestNames(DRYTest): """ 'names', what other languages call variables... """ @@ -1018,5 +1037,40 @@ self.t('1 > 2 < foo(22)', False) self.assertListEqual(x, []) + +class TestDisallowedFunctions(DRYTest): + def test_functions_are_disallowed_at_init(self): + DISALLOWED = [type, isinstance, eval, getattr, setattr, help, repr, compile, open] + if simpleeval.PYTHON3: + exec('DISALLOWED.append(exec)') # exec is not a function in Python2... + + for f in simpleeval.DISALLOW_FUNCTIONS: + assert f in DISALLOWED + + for x in DISALLOWED: + with self.assertRaises(FeatureNotAvailable): + s = SimpleEval(functions ={'foo': x}) + + def test_functions_are_disallowed_in_expressions(self): + DISALLOWED = [type, isinstance, eval, getattr, setattr, help, repr, compile, open] + + if simpleeval.PYTHON3: + exec('DISALLOWED.append(exec)') # exec is not a function in Python2... + + for f in simpleeval.DISALLOW_FUNCTIONS: + assert f in DISALLOWED + + + DF = simpleeval.DEFAULT_FUNCTIONS.copy() + + for x in DISALLOWED: + simpleeval.DEFAULT_FUNCTIONS = DF.copy() + with self.assertRaises(FeatureNotAvailable): + s = SimpleEval() + s.functions['foo'] = x + s.eval('foo(42)') + + simpleeval.DEFAULT_FUNCTIONS = DF.copy() + if __name__ == '__main__': # pragma: no cover unittest.main()
