RestrictedPython 7.2a1.dev0__py3-none-any.whl → 7.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,6 +18,7 @@
18
18
  import builtins
19
19
 
20
20
  from RestrictedPython._compat import IS_PY311_OR_GREATER
21
+ from RestrictedPython.transformer import INSPECT_ATTRIBUTES
21
22
 
22
23
 
23
24
  safe_builtins = {}
@@ -239,6 +240,9 @@ def guarded_delattr(object, name):
239
240
  safe_builtins['delattr'] = guarded_delattr
240
241
 
241
242
 
243
+ raise_ = object()
244
+
245
+
242
246
  def safer_getattr(object, name, default=None, getattr=getattr):
243
247
  """Getattr implementation which prevents using format on string objects.
244
248
 
@@ -246,22 +250,34 @@ def safer_getattr(object, name, default=None, getattr=getattr):
246
250
  http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/
247
251
 
248
252
  """
253
+ if type(name) is not str:
254
+ raise TypeError('type(name) must be str')
249
255
  if name in ('format', 'format_map') and (
250
256
  isinstance(object, str) or
251
257
  (isinstance(object, type) and issubclass(object, str))):
252
258
  raise NotImplementedError(
253
259
  'Using the format*() methods of `str` is not safe')
260
+ if name in INSPECT_ATTRIBUTES:
261
+ raise AttributeError(
262
+ f'"{name}" is a restricted name,'
263
+ ' that is forbidden to access in RestrictedPython.')
254
264
  if name.startswith('_'):
255
265
  raise AttributeError(
256
266
  '"{name}" is an invalid attribute name because it '
257
267
  'starts with "_"'.format(name=name)
258
268
  )
259
- return getattr(object, name, default)
269
+ args = (object, name) + (() if default is raise_ else (default,))
270
+ return getattr(*args)
260
271
 
261
272
 
262
273
  safe_builtins['_getattr_'] = safer_getattr
263
274
 
264
275
 
276
+ def safer_getattr_raise(object, name, default=raise_):
277
+ """like ``safer_getattr`` but raising ``AttributeError`` if failing."""
278
+ return safer_getattr(object, name, default)
279
+
280
+
265
281
  def guarded_iter_unpack_sequence(it, spec, _getiter_):
266
282
  """Protect sequence unpacking of targets in a 'for loop'.
267
283
 
@@ -29,7 +29,11 @@ class _AttributeDelegator:
29
29
  if attr in self.__excludes:
30
30
  raise NotImplementedError(
31
31
  f"{self.__mod.__name__}.{attr} is not safe")
32
- return getattr(self.__mod, attr)
32
+ try:
33
+ return getattr(self.__mod, attr)
34
+ except AttributeError as e:
35
+ e.obj = self
36
+ raise
33
37
 
34
38
 
35
39
  utility_builtins['string'] = _AttributeDelegator(string, "Formatter")
@@ -3,7 +3,6 @@ import sys
3
3
 
4
4
 
5
5
  _version = sys.version_info
6
- IS_PY38_OR_GREATER = _version.major == 3 and _version.minor >= 8
7
6
  IS_PY310_OR_GREATER = _version.major == 3 and _version.minor >= 10
8
7
  IS_PY311_OR_GREATER = _version.major == 3 and _version.minor >= 11
9
8
  IS_PY312_OR_GREATER = _version.major == 3 and _version.minor >= 12
@@ -22,16 +22,6 @@ import ast
22
22
  import contextlib
23
23
  import textwrap
24
24
 
25
- from ._compat import IS_PY38_OR_GREATER
26
-
27
-
28
- # Avoid DeprecationWarnings under Python 3.12 and up
29
- if IS_PY38_OR_GREATER:
30
- astStr = ast.Constant
31
- astNum = ast.Constant
32
- else: # pragma: no cover
33
- astStr = ast.Str
34
- astNum = ast.Num
35
25
 
36
26
  # For AugAssign the operator must be converted to a string.
37
27
  IOPERATOR_TO_STR = {
@@ -127,16 +117,14 @@ def copy_locations(new_node, old_node):
127
117
  assert 'lineno' in new_node._attributes
128
118
  new_node.lineno = old_node.lineno
129
119
 
130
- if IS_PY38_OR_GREATER:
131
- assert 'end_lineno' in new_node._attributes
132
- new_node.end_lineno = old_node.end_lineno
120
+ assert 'end_lineno' in new_node._attributes
121
+ new_node.end_lineno = old_node.end_lineno
133
122
 
134
123
  assert 'col_offset' in new_node._attributes
135
124
  new_node.col_offset = old_node.col_offset
136
125
 
137
- if IS_PY38_OR_GREATER:
138
- assert 'end_col_offset' in new_node._attributes
139
- new_node.end_col_offset = old_node.end_col_offset
126
+ assert 'end_col_offset' in new_node._attributes
127
+ new_node.end_col_offset = old_node.end_col_offset
140
128
 
141
129
  ast.fix_missing_locations(new_node)
142
130
 
@@ -280,7 +268,7 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
280
268
  """
281
269
  spec = ast.Dict(keys=[], values=[])
282
270
 
283
- spec.keys.append(astStr('childs'))
271
+ spec.keys.append(ast.Constant('childs'))
284
272
  spec.values.append(ast.Tuple([], ast.Load()))
285
273
 
286
274
  # starred elements in a sequence do not contribute into the min_len.
@@ -300,12 +288,12 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
300
288
 
301
289
  elif isinstance(val, ast.Tuple):
302
290
  el = ast.Tuple([], ast.Load())
303
- el.elts.append(astNum(idx - offset))
291
+ el.elts.append(ast.Constant(idx - offset))
304
292
  el.elts.append(self.gen_unpack_spec(val))
305
293
  spec.values[0].elts.append(el)
306
294
 
307
- spec.keys.append(astStr('min_len'))
308
- spec.values.append(astNum(min_len))
295
+ spec.keys.append(ast.Constant('min_len'))
296
+ spec.values.append(ast.Constant(min_len))
309
297
 
310
298
  return spec
311
299
 
@@ -492,9 +480,8 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
492
480
  if isinstance(node, ast.Module):
493
481
  _print.lineno = position
494
482
  _print.col_offset = position
495
- if IS_PY38_OR_GREATER:
496
- _print.end_lineno = position
497
- _print.end_col_offset = position
483
+ _print.end_lineno = position
484
+ _print.end_col_offset = position
498
485
  ast.fix_missing_locations(_print)
499
486
  else:
500
487
  copy_locations(_print, node)
@@ -535,63 +522,26 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
535
522
 
536
523
  # ast for Literals
537
524
 
538
- if IS_PY38_OR_GREATER:
539
-
540
- def visit_Constant(self, node):
541
- """Allow constant literals with restriction for Ellipsis.
542
-
543
- Constant replaces Num, Str, Bytes, NameConstant and Ellipsis in
544
- Python 3.8+.
545
- :see: https://docs.python.org/dev/whatsnew/3.8.html#deprecated
546
- """
547
- if node.value is Ellipsis:
548
- # Deny using `...`.
549
- # Special handling necessary as ``self.not_allowed(node)``
550
- # would return the Error Message:
551
- # 'Constant statements are not allowed.'
552
- # which is only partial true.
553
- self.error(node, 'Ellipsis statements are not allowed.')
554
- return
555
- return self.node_contents_visit(node)
556
-
557
- else:
558
-
559
- def visit_Num(self, node):
560
- """Allow integer numbers without restrictions.
561
-
562
- Replaced by Constant in Python 3.8.
563
- """
564
- return self.node_contents_visit(node)
565
-
566
- def visit_Str(self, node):
567
- """Allow string literals without restrictions.
568
-
569
- Replaced by Constant in Python 3.8.
570
- """
571
- return self.node_contents_visit(node)
525
+ def visit_Constant(self, node):
526
+ """Allow constant literals with restriction for Ellipsis.
572
527
 
573
- def visit_Bytes(self, node):
574
- """Allow bytes literals without restrictions.
575
-
576
- Replaced by Constant in Python 3.8.
577
- """
578
- return self.node_contents_visit(node)
579
-
580
- def visit_Ellipsis(self, node):
581
- """Deny using `...`.
582
-
583
- Replaced by Constant in Python 3.8.
584
- """
585
- return self.not_allowed(node)
586
-
587
- def visit_NameConstant(self, node):
588
- """Allow constant literals (True, False, None) without ...
589
-
590
- restrictions.
528
+ Constant replaces Num, Str, Bytes, NameConstant and Ellipsis in
529
+ Python 3.8+.
530
+ :see: https://docs.python.org/dev/whatsnew/3.8.html#deprecated
531
+ """
532
+ if node.value is Ellipsis:
533
+ # Deny using `...`.
534
+ # Special handling necessary as ``self.not_allowed(node)``
535
+ # would return the Error Message:
536
+ # 'Constant statements are not allowed.'
537
+ # which is only partial true.
538
+ self.error(node, 'Ellipsis statements are not allowed.')
539
+ return
540
+ return self.node_contents_visit(node)
591
541
 
592
- Replaced by Constant in Python 3.8.
593
- """
594
- return self.node_contents_visit(node)
542
+ def visit_Interactive(self, node):
543
+ """Allow single mode without restrictions."""
544
+ return self.node_contents_visit(node)
595
545
 
596
546
  def visit_List(self, node):
597
547
  """Allow list literals without restrictions."""
@@ -911,7 +861,7 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
911
861
  node = self.node_contents_visit(node)
912
862
  new_node = ast.Call(
913
863
  func=ast.Name('_getattr_', ast.Load()),
914
- args=[node.value, astStr(node.attr)],
864
+ args=[node.value, ast.Constant(node.attr)],
915
865
  keywords=[])
916
866
 
917
867
  copy_locations(new_node, node)
@@ -1115,7 +1065,7 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
1115
1065
  value=ast.Call(
1116
1066
  func=ast.Name('_inplacevar_', ast.Load()),
1117
1067
  args=[
1118
- astStr(IOPERATOR_TO_STR[type(node.op)]),
1068
+ ast.Constant(IOPERATOR_TO_STR[type(node.op)]),
1119
1069
  ast.Name(node.target.id, ast.Load()),
1120
1070
  node.value
1121
1071
  ],
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: RestrictedPython
3
- Version: 7.2a1.dev0
3
+ Version: 7.4
4
4
  Summary: RestrictedPython is a defined subset of the Python language which allows to provide a program input into a trusted environment.
5
5
  Home-page: https://github.com/zopefoundation/RestrictedPython
6
6
  Author: Zope Foundation and Contributors
7
- Author-email: zope-dev@zope.org
7
+ Author-email: zope-dev@zope.dev
8
8
  License: ZPL 2.1
9
9
  Project-URL: Documentation, https://restrictedpython.readthedocs.io/
10
10
  Project-URL: Source, https://github.com/zopefoundation/RestrictedPython
@@ -15,23 +15,23 @@ Classifier: License :: OSI Approved :: Zope Public License
15
15
  Classifier: Programming Language :: Python
16
16
  Classifier: Operating System :: OS Independent
17
17
  Classifier: Programming Language :: Python :: 3
18
- Classifier: Programming Language :: Python :: 3.7
19
18
  Classifier: Programming Language :: Python :: 3.8
20
19
  Classifier: Programming Language :: Python :: 3.9
21
20
  Classifier: Programming Language :: Python :: 3.10
22
21
  Classifier: Programming Language :: Python :: 3.11
23
22
  Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
24
  Classifier: Programming Language :: Python :: Implementation :: CPython
25
25
  Classifier: Topic :: Security
26
- Requires-Python: >=3.7, <3.14
26
+ Requires-Python: >=3.8, <3.14
27
27
  Description-Content-Type: text/x-rst
28
28
  License-File: LICENSE.txt
29
29
  Provides-Extra: docs
30
- Requires-Dist: Sphinx ; extra == 'docs'
31
- Requires-Dist: sphinx-rtd-theme ; extra == 'docs'
30
+ Requires-Dist: Sphinx; extra == "docs"
31
+ Requires-Dist: furo; extra == "docs"
32
32
  Provides-Extra: test
33
- Requires-Dist: pytest ; extra == 'test'
34
- Requires-Dist: pytest-mock ; extra == 'test'
33
+ Requires-Dist: pytest; extra == "test"
34
+ Requires-Dist: pytest-mock; extra == "test"
35
35
 
36
36
  .. image:: https://github.com/zopefoundation/RestrictedPython/actions/workflows/tests.yml/badge.svg
37
37
  :target: https://github.com/zopefoundation/RestrictedPython/actions/workflows/tests.yml
@@ -124,11 +124,39 @@ the documentation `Contributing page
124
124
  Changes
125
125
  =======
126
126
 
127
- 7.2a1.dev0 (2024-03-14)
128
- -----------------------
127
+ 7.4 (2024-10-09)
128
+ ----------------
129
+
130
+ - Allow to use the package with Python 3.13.
131
+
132
+ - Drop support for Python 3.7.
133
+
134
+ - Provide new function ``RestrictedPython.Guards.safer_getattr_raise``.
135
+ It is similar to ``safer_getattr`` but handles its parameter
136
+ ``default`` like ``getattr``, i.e. it raises ``AttributeError``
137
+ if the attribute lookup fails and this parameter is not provided,
138
+ fixes `#287 <https://github.com/zopefoundation/RestrictedPython/issues/287>`_.
139
+
140
+
141
+ 7.3 (2024-09-30)
142
+ ----------------
143
+
144
+ - Increase the safety level of ``safer_getattr`` allowing applications to use
145
+ it as ``getattr`` implementation. Such use should now follow the same policy
146
+ and give the same level of protection as direct attribute access in an
147
+ environment based on ``RestrictedPython``'s ``safe_builtints``.
148
+ - Prevent information leakage via ``AttributeError.obj``
149
+ and the ``string`` module. (CVE-2024-47532)
150
+
151
+
152
+ 7.2 (2024-08-02)
153
+ ----------------
129
154
 
130
- - Allow to use the package with Python 3.13 -- Caution: No security
131
- audit has been done so far.
155
+ - Remove unneeded setuptools fossils that may cause installation problems
156
+ with recent setuptools versions.
157
+ - Add support for single mode statements / execution.
158
+ - Fix a potential breakout capability in the provided ``safer_getattr`` method
159
+ that is part of the ``safer_builtins``.
132
160
 
133
161
 
134
162
  7.1 (2024-03-14)
@@ -0,0 +1,14 @@
1
+ RestrictedPython/Eval.py,sha256=pa79tc-JsT7xfzwg0ceMkxyioIEnFbNHc_PsKUhkkj8,3201
2
+ RestrictedPython/Guards.py,sha256=Ls4eJa94nj6z6L65faEBCX8m7dHr3iF4n8-HlFpMniE,8217
3
+ RestrictedPython/Limits.py,sha256=dORpuly21vSjy8gzNac9IYfIXMMWRVFvqUiKKIeZ3OM,1866
4
+ RestrictedPython/PrintCollector.py,sha256=bBCpnUPOuKz1wJDuSgh7wo2aoKfcTJeeT8OYnM-K9F8,1137
5
+ RestrictedPython/Utilities.py,sha256=u4HUdyjGawaeHyXSakyt4gRT17BZietXnF5WqicujjE,3033
6
+ RestrictedPython/__init__.py,sha256=qB_s6zDxuXPAGMoKYKBMc-xZ0gTnQ0ZvtY5FxdAG3aM,1862
7
+ RestrictedPython/_compat.py,sha256=2Mew5xHBB0Lg3YfhbFyTdOSt4TQCWnEBGQ1SNFeR8a0,318
8
+ RestrictedPython/compile.py,sha256=IhcF733t-bkPcvfQ2_NyBeCbSIPtHYxR-GQNNHnaMHM,6727
9
+ RestrictedPython/transformer.py,sha256=qpvsswxFDkVTra48qxQivnAbBoVdmEVLgdDKCwwt2cI,41418
10
+ RestrictedPython-7.4.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
11
+ RestrictedPython-7.4.dist-info/METADATA,sha256=oU8AXsXRUKtaYTnteX0ulTyVZQVM2gQBdXeRDGwKLHg,13448
12
+ RestrictedPython-7.4.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
13
+ RestrictedPython-7.4.dist-info/top_level.txt,sha256=E1-3ARWcduVJnQAScms0FgqnBx_PovrzYsNMYuLGwa0,17
14
+ RestrictedPython-7.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: setuptools (73.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,14 +0,0 @@
1
- RestrictedPython/Eval.py,sha256=pa79tc-JsT7xfzwg0ceMkxyioIEnFbNHc_PsKUhkkj8,3201
2
- RestrictedPython/Guards.py,sha256=XXupE0TwcWdb6qAsSexWUYEIeT3bVLTdOVvn94eoqs0,7646
3
- RestrictedPython/Limits.py,sha256=dORpuly21vSjy8gzNac9IYfIXMMWRVFvqUiKKIeZ3OM,1866
4
- RestrictedPython/PrintCollector.py,sha256=bBCpnUPOuKz1wJDuSgh7wo2aoKfcTJeeT8OYnM-K9F8,1137
5
- RestrictedPython/Utilities.py,sha256=7R6Op1Oqw9-fSxy_eWVa6ioZPx-SAxa7OolDObTWRkU,2937
6
- RestrictedPython/__init__.py,sha256=qB_s6zDxuXPAGMoKYKBMc-xZ0gTnQ0ZvtY5FxdAG3aM,1862
7
- RestrictedPython/_compat.py,sha256=nacdAJi4E8GKhkR99_BAxMA0AtK2FQnvrqZbG8hGofc,383
8
- RestrictedPython/compile.py,sha256=IhcF733t-bkPcvfQ2_NyBeCbSIPtHYxR-GQNNHnaMHM,6727
9
- RestrictedPython/transformer.py,sha256=AsPDuEN42OrBZBDtDCOFcWssNZrvm8PBGku8IvREXFg,42766
10
- RestrictedPython-7.2a1.dev0.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
11
- RestrictedPython-7.2a1.dev0.dist-info/METADATA,sha256=V23yHfhhH7oSZr2ClO4fp6hkl0XVT5Xr1bveMPANdfw,12397
12
- RestrictedPython-7.2a1.dev0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
13
- RestrictedPython-7.2a1.dev0.dist-info/top_level.txt,sha256=E1-3ARWcduVJnQAScms0FgqnBx_PovrzYsNMYuLGwa0,17
14
- RestrictedPython-7.2a1.dev0.dist-info/RECORD,,