Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Romain Courteaud
erp5
Commits
b8b49b2c
Commit
b8b49b2c
authored
Apr 15, 2022
by
Arnaud Fontaine
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
py3: RestrictedPython: Port code and allow Python3/six modules.
parent
2a3e24e0
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
110 additions
and
26 deletions
+110
-26
product/ERP5/Document/BusinessTemplate.py
product/ERP5/Document/BusinessTemplate.py
+1
-0
product/ERP5Type/Six.py
product/ERP5Type/Six.py
+52
-0
product/ERP5Type/patches/Restricted.py
product/ERP5Type/patches/Restricted.py
+57
-26
No files found.
product/ERP5/Document/BusinessTemplate.py
View file @
b8b49b2c
...
@@ -6734,6 +6734,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
...
@@ -6734,6 +6734,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
# Monkey patches or used by monkey patches ; Restricted Python
# Monkey patches or used by monkey patches ; Restricted Python
'Products.ERP5Type.Calendar'
,
'Products.ERP5Type.Calendar'
,
'Products.ERP5Type.Collections'
,
'Products.ERP5Type.Collections'
,
'Products.ERP5Type.Six'
,
'Products.ERP5Type.Timeout'
,
'Products.ERP5Type.Timeout'
,
'Products.ERP5Type.ZipFile'
,
'Products.ERP5Type.ZipFile'
,
'Products.ERP5Type.ZopePatch'
,
'Products.ERP5Type.ZopePatch'
,
...
...
product/ERP5Type/Six.py
0 → 100644
View file @
b8b49b2c
##############################################################################
#
# Copyright (c) 2022 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
"""
Restricted six module.
From restricted python, use "import six" (see patches/Restricted.py).
"""
import
six
as
_six
PY2
=
_six
.
PY2
PY3
=
_six
.
PY3
moves
=
_six
.
moves
text_type
=
_six
.
text_type
binary_type
=
_six
.
binary_type
string_types
=
_six
.
string_types
integer_types
=
_six
.
integer_types
# ContainerAssertions cannot be used here (like for dict) because the following
# functions are defined on `six` module directly and ContainerAssertions has a
# type() as key
from
Products.ERP5Type.patches.Restricted
import
SafeIterItems
iteritems
=
lambda
d
:
SafeIterItems
(
_six
.
iteritems
(
d
),
d
)
from
AccessControl.ZopeGuards
import
SafeIter
iterkeys
=
lambda
d
:
SafeIter
(
_six
.
iterkeys
(
d
),
d
)
itervalues
=
lambda
d
:
SafeIter
(
_six
.
itervalues
(
d
),
d
)
from
AccessControl.ZopeGuards
import
safe_builtins
as
_safe_builtins
_safe_builtins
[
'xrange'
]
=
_six
.
moves
.
xrange
product/ERP5Type/patches/Restricted.py
View file @
b8b49b2c
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
#
#
##############################################################################
##############################################################################
import
six
import
copy
import
copy
import
sys
import
sys
import
types
import
types
...
@@ -128,34 +129,47 @@ class TypeAccessChecker:
...
@@ -128,34 +129,47 @@ class TypeAccessChecker:
return
v
return
v
return
factory
return
factory
def
__
nonzero
__
(
self
):
def
__
bool
__
(
self
):
# If Containers(type(x)) is true, ZopeGuard checks will short circuit,
# If Containers(type(x)) is true, ZopeGuard checks will short circuit,
# thinking it's a simple type, but we don't want this for type, because
# thinking it's a simple type, but we don't want this for type, because
# type(x) is type for classes, being trueish would skip security check on
# type(x) is type for classes, being trueish would skip security check on
# classes.
# classes.
return
False
return
False
__nonzero__
=
__bool__
# six.PY2
ContainerAssertions
[
type
]
=
TypeAccessChecker
()
ContainerAssertions
[
type
]
=
TypeAccessChecker
()
class
SafeIterItems
(
SafeIter
):
class
SafeIterItems
(
SafeIter
):
def
next
(
self
):
def
__next__
(
self
):
ob
=
self
.
_next
()
try
:
ob
=
self
.
_next
()
# AccessControl 2.13
except
AttributeError
:
ob
=
next
(
self
.
_iter
)
# AccessControl 4.x
c
=
self
.
container
c
=
self
.
container
guard
(
c
,
ob
[
0
])
guard
(
c
,
ob
[
0
])
guard
(
c
,
ob
[
1
])
guard
(
c
,
ob
[
1
])
return
ob
return
ob
next
=
__next__
# six.PY2
def
get_iteritems
(
c
,
name
):
def
get_iteritems
(
c
,
name
):
return
lambda
:
SafeIterItems
(
c
.
iteritems
(
),
c
)
return
lambda
:
SafeIterItems
(
six
.
iteritems
(
c
),
c
)
_dict_white_list
[
'iteritems'
]
=
get_iteritems
_dict_white_list
[
'iteritems'
]
=
get_iteritems
import
past.builtins
# six.PY2
allow_module
(
'past.builtins'
)
ModuleSecurityInfo
(
'past.builtins'
).
declarePublic
(
'cmp'
)
def
guarded_sorted
(
seq
,
cmp
=
None
,
key
=
None
,
reverse
=
False
):
def
guarded_sorted
(
seq
,
cmp
=
None
,
key
=
None
,
reverse
=
False
):
if
cmp
is
not
None
:
# six.PY2
from
functools
import
cmp_to_key
key
=
cmp_to_key
(
cmp
)
if
not
isinstance
(
seq
,
SafeIter
):
if
not
isinstance
(
seq
,
SafeIter
):
for
i
,
x
in
enumerate
(
seq
):
for
i
,
x
in
enumerate
(
seq
):
guard
(
seq
,
x
,
i
)
guard
(
seq
,
x
,
i
)
return
sorted
(
seq
,
cmp
=
cmp
,
key
=
key
,
reverse
=
reverse
)
return
sorted
(
seq
,
key
=
key
,
reverse
=
reverse
)
safe_builtins
[
'sorted'
]
=
guarded_sorted
safe_builtins
[
'sorted'
]
=
guarded_sorted
def
guarded_reversed
(
seq
):
def
guarded_reversed
(
seq
):
...
@@ -225,8 +239,6 @@ from RestrictedPython.Guards import full_write_guard
...
@@ -225,8 +239,6 @@ from RestrictedPython.Guards import full_write_guard
ContainerAssertions
[
defaultdict
]
=
_check_access_wrapper
(
defaultdict
,
_dict_white_list
)
ContainerAssertions
[
defaultdict
]
=
_check_access_wrapper
(
defaultdict
,
_dict_white_list
)
full_write_guard
.
func_closure
[
1
].
cell_contents
.
__self__
[
defaultdict
]
=
True
full_write_guard
.
func_closure
[
1
].
cell_contents
.
__self__
[
defaultdict
]
=
True
# In contrary to builtins such as dict/defaultdict, it is possible to set
# attributes on OrderedDict instances, so only allow setitem/delitem
ContainerAssertions
[
OrderedDict
]
=
_check_access_wrapper
(
OrderedDict
,
_dict_white_list
)
ContainerAssertions
[
OrderedDict
]
=
_check_access_wrapper
(
OrderedDict
,
_dict_white_list
)
OrderedDict
.
__guarded_setitem__
=
OrderedDict
.
__setitem__
.
__func__
OrderedDict
.
__guarded_setitem__
=
OrderedDict
.
__setitem__
.
__func__
OrderedDict
.
__guarded_delitem__
=
OrderedDict
.
__delitem__
.
__func__
OrderedDict
.
__guarded_delitem__
=
OrderedDict
.
__delitem__
.
__func__
...
@@ -258,16 +270,18 @@ allow_type(type(re.compile('')))
...
@@ -258,16 +270,18 @@ allow_type(type(re.compile('')))
allow_type
(
type
(
re
.
match
(
'x'
,
'x'
)))
allow_type
(
type
(
re
.
match
(
'x'
,
'x'
)))
allow_type
(
type
(
re
.
finditer
(
'x'
,
'x'
)))
allow_type
(
type
(
re
.
finditer
(
'x'
,
'x'
)))
allow_module
(
'StringIO'
)
import
StringIO
StringIO
.
StringIO
.
__allow_access_to_unprotected_subobjects__
=
1
allow_module
(
'cStringIO'
)
import
cStringIO
allow_type
(
cStringIO
.
InputType
)
allow_type
(
cStringIO
.
OutputType
)
allow_module
(
'io'
)
allow_module
(
'io'
)
import
io
import
io
allow_type
(
io
.
BytesIO
)
allow_type
(
io
.
BytesIO
)
allow_type
(
io
.
StringIO
)
if
six
.
PY2
:
allow_module
(
'StringIO'
)
import
StringIO
StringIO
.
StringIO
.
__allow_access_to_unprotected_subobjects__
=
1
allow_module
(
'cStringIO'
)
import
cStringIO
allow_type
(
cStringIO
.
InputType
)
allow_type
(
cStringIO
.
OutputType
)
ModuleSecurityInfo
(
'cgi'
).
declarePublic
(
'escape'
,
'parse_header'
)
ModuleSecurityInfo
(
'cgi'
).
declarePublic
(
'escape'
,
'parse_header'
)
allow_module
(
'datetime'
)
allow_module
(
'datetime'
)
...
@@ -307,10 +321,28 @@ import hashlib
...
@@ -307,10 +321,28 @@ import hashlib
allow_type
(
type
(
hashlib
.
md5
()))
allow_type
(
type
(
hashlib
.
md5
()))
allow_module
(
'time'
)
allow_module
(
'time'
)
allow_module
(
'unicodedata'
)
allow_module
(
'unicodedata'
)
allow_module
(
'urlparse'
)
import
urlparse
if
six
.
PY2
:
allow_type
(
urlparse
.
ParseResult
)
import
urlparse
allow_type
(
urlparse
.
SplitResult
)
allow_module
(
'urlparse'
)
allow_type
(
urlparse
.
ParseResult
)
allow_type
(
urlparse
.
SplitResult
)
ModuleSecurityInfo
(
'urllib'
).
declarePublic
(
'urlencode'
,
'quote'
,
'unquote'
,
'quote_plus'
,
'unquote_plus'
,
)
import
six.moves.urllib.parse
allow_module
(
'six.moves.urllib.parse'
)
allow_type
(
six
.
moves
.
urllib
.
parse
.
ParseResult
)
allow_type
(
six
.
moves
.
urllib
.
parse
.
SplitResult
)
ModuleSecurityInfo
(
'six.moves.urllib.parse'
).
declarePublic
(
'urlencode'
,
'quote'
,
'unquote'
,
'quote_plus'
,
'unquote_plus'
,
)
allow_module
(
'struct'
)
allow_module
(
'struct'
)
allow_module
(
'zlib'
)
allow_module
(
'zlib'
)
...
@@ -338,14 +370,19 @@ MNAME_MAP = {
...
@@ -338,14 +370,19 @@ MNAME_MAP = {
'zipfile'
:
'Products.ERP5Type.ZipFile'
,
'zipfile'
:
'Products.ERP5Type.ZipFile'
,
'calendar'
:
'Products.ERP5Type.Calendar'
,
'calendar'
:
'Products.ERP5Type.Calendar'
,
'collections'
:
'Products.ERP5Type.Collections'
,
'collections'
:
'Products.ERP5Type.Collections'
,
'six'
:
'Products.ERP5Type.Six'
,
}
}
for
alias
,
real
in
MNAME_MAP
.
items
(
):
for
alias
,
real
in
six
.
iteritems
(
MNAME_MAP
):
assert
'.'
not
in
alias
,
alias
# TODO: support this
assert
'.'
not
in
alias
,
alias
# TODO: support this
allow_module
(
real
)
allow_module
(
real
)
del
alias
,
real
del
alias
,
real
orig_guarded_import
=
safe_builtins
[
'__import__'
]
orig_guarded_import
=
safe_builtins
[
'__import__'
]
try
:
from
AccessControl.ZopeGuards
import
import_default_level
# zope4py3
except
ImportError
:
import_default_level
=
-
1
def
guarded_import
(
mname
,
globals
=
None
,
locals
=
None
,
fromlist
=
None
,
def
guarded_import
(
mname
,
globals
=
None
,
locals
=
None
,
fromlist
=
None
,
level
=
-
1
):
level
=
import_default_level
):
for
fromname
in
fromlist
or
():
for
fromname
in
fromlist
or
():
if
fromname
[:
1
]
==
'_'
:
if
fromname
[:
1
]
==
'_'
:
raise
Unauthorized
(
fromname
)
raise
Unauthorized
(
fromname
)
...
@@ -375,12 +412,6 @@ safe_builtins['__import__'] = guarded_import
...
@@ -375,12 +412,6 @@ safe_builtins['__import__'] = guarded_import
ModuleSecurityInfo
(
'transaction'
).
declarePublic
(
'doom'
)
ModuleSecurityInfo
(
'transaction'
).
declarePublic
(
'doom'
)
ModuleSecurityInfo
(
'urllib'
).
declarePublic
(
'urlencode'
,
'quote'
,
'unquote'
,
'quote_plus'
,
'unquote_plus'
,
)
import
hmac
import
hmac
allow_module
(
'hmac'
)
allow_module
(
'hmac'
)
# HMAC does not sub-class object so ContainerAssertions
# HMAC does not sub-class object so ContainerAssertions
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment