Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
268fd5a9
Commit
268fd5a9
authored
Dec 28, 2009
by
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- resolved a circular import issue by moving TaintedString out of ZPublisher
parent
e2266001
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
234 additions
and
215 deletions
+234
-215
doc/CHANGES.rst
doc/CHANGES.rst
+3
-0
src/DocumentTemplate/DT_Util.py
src/DocumentTemplate/DT_Util.py
+42
-43
src/DocumentTemplate/DT_Var.py
src/DocumentTemplate/DT_Var.py
+6
-10
src/DocumentTemplate/tests/test_DT_Var.py
src/DocumentTemplate/tests/test_DT_Var.py
+1
-2
src/Shared/TaintedString/__init__.py
src/Shared/TaintedString/__init__.py
+155
-0
src/Shared/TaintedString/tests.py
src/Shared/TaintedString/tests.py
+10
-18
src/ZPublisher/HTTPRequest.py
src/ZPublisher/HTTPRequest.py
+1
-1
src/ZPublisher/TaintedString.py
src/ZPublisher/TaintedString.py
+9
-138
src/ZPublisher/tests/testHTTPRequest.py
src/ZPublisher/tests/testHTTPRequest.py
+7
-3
No files found.
doc/CHANGES.rst
View file @
268fd5a9
...
...
@@ -11,6 +11,9 @@ Trunk (unreleased)
Restructuring
+++++++++++++
- Moved TaintedString from ZPublisher to Shared.
This resolves a circular import issue.
- Moved zope.formlib / zope.app.form integration into a separate package
called five.formlib.
...
...
src/DocumentTemplate/DT_Util.py
View file @
268fd5a9
...
...
@@ -12,9 +12,13 @@
##############################################################################
"""DTML Utilities
$Id$"""
$Id$
"""
import
re
import
string
from
types
import
BuiltinFunctionType
from
types
import
FunctionType
# for import by other modules, dont remove!
from
DocumentTemplate.html_quote
import
html_quote
,
ustr
...
...
@@ -27,6 +31,8 @@ from RestrictedPython.Guards import safe_builtins
from
RestrictedPython.Utilities
import
utility_builtins
from
RestrictedPython.Eval
import
RestrictionCapableEval
from
Shared.TaintedString
import
TaintedString
test
=
utility_builtins
[
'test'
]
# for backwards compatibility, dont remove!
LIMITED_BUILTINS
=
1
...
...
@@ -68,48 +74,41 @@ if LIMITED_BUILTINS:
f
=
NotBindable
(
f
)
setattr
(
TemplateDict
,
name
,
f
)
try
:
# Wrap the string module so it can deal with TaintedString strings.
from
ZPublisher.TaintedString
import
TaintedString
from
types
import
FunctionType
,
BuiltinFunctionType
,
StringType
import
string
class
StringModuleWrapper
:
def
__getattr__
(
self
,
key
):
attr
=
getattr
(
string
,
key
)
if
(
isinstance
(
attr
,
FunctionType
)
or
isinstance
(
attr
,
BuiltinFunctionType
)):
return
StringFunctionWrapper
(
attr
)
else
:
return
attr
class
StringFunctionWrapper
:
def
__init__
(
self
,
method
):
self
.
_method
=
method
def
__call__
(
self
,
*
args
,
**
kw
):
tainted
=
0
args
=
list
(
args
)
for
i
in
range
(
len
(
args
)):
if
isinstance
(
args
[
i
],
TaintedString
):
tainted
=
1
args
[
i
]
=
str
(
args
[
i
])
for
k
,
v
in
kw
.
items
():
if
isinstance
(
v
,
TaintedString
):
tainted
=
1
kw
[
k
]
=
str
(
v
)
args
=
tuple
(
args
)
retval
=
self
.
_method
(
*
args
,
**
kw
)
if
tainted
and
isinstance
(
retval
,
StringType
)
and
'<'
in
retval
:
retval
=
TaintedString
(
retval
)
return
retval
TemplateDict
.
string
=
StringModuleWrapper
()
except
ImportError
:
# Use the string module already defined in RestrictedPython.Utilities
pass
# Wrap the string module so it can deal with TaintedString strings.
class
StringModuleWrapper
:
def
__getattr__
(
self
,
key
):
attr
=
getattr
(
string
,
key
)
if
(
isinstance
(
attr
,
FunctionType
)
or
isinstance
(
attr
,
BuiltinFunctionType
)):
return
StringFunctionWrapper
(
attr
)
else
:
return
attr
class
StringFunctionWrapper
:
def
__init__
(
self
,
method
):
self
.
_method
=
method
def
__call__
(
self
,
*
args
,
**
kw
):
tainted
=
0
args
=
list
(
args
)
for
i
in
range
(
len
(
args
)):
if
isinstance
(
args
[
i
],
TaintedString
):
tainted
=
1
args
[
i
]
=
str
(
args
[
i
])
for
k
,
v
in
kw
.
items
():
if
isinstance
(
v
,
TaintedString
):
tainted
=
1
kw
[
k
]
=
str
(
v
)
args
=
tuple
(
args
)
retval
=
self
.
_method
(
*
args
,
**
kw
)
if
tainted
and
isinstance
(
retval
,
str
)
and
'<'
in
retval
:
retval
=
TaintedString
(
retval
)
return
retval
TemplateDict
.
string
=
StringModuleWrapper
()
# The functions below are meant to bind to the TemplateDict.
...
...
src/DocumentTemplate/DT_Var.py
View file @
268fd5a9
...
...
@@ -7,10 +7,10 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
# FOR A PARTICULAR PURPOSE
.
#
##############################################################################
__doc__
=
'''
Variable insertion parameters
"""
Variable insertion parameters
When inserting variables, parameters may be specified to
control how the data will be formatted. In HTML source, the
...
...
@@ -149,14 +149,10 @@ Evaluating expressions without rendering results
A 'call' tag is provided for evaluating named objects or expressions
without rendering the result.
'''
# '
__rcs_id__
=
'$Id$'
__version__
=
'$Revision: 1.60 $'
[
11
:
-
2
]
$Id$
"""
import
string
,
re
,
sys
from
cgi
import
escape
from
urllib
import
quote
,
quote_plus
,
unquote
,
unquote_plus
# for import by other modules, dont remove!
...
...
@@ -164,8 +160,8 @@ from DocumentTemplate.html_quote import html_quote
from
DocumentTemplate.DT_Util
import
parse_params
,
name_param
,
str
,
ustr
from
Acquisition
import
aq_base
from
ZPublisher
.TaintedString
import
TaintedString
from
zope.structuredtext.html
import
HTML
WithImages
,
HTML
from
Shared
.TaintedString
import
TaintedString
from
zope.structuredtext.html
import
HTML
from
zope.structuredtext.document
import
DocumentWithImages
from
App.config
import
getConfiguration
...
...
src/DocumentTemplate/tests/test_DT_Var.py
View file @
268fd5a9
...
...
@@ -44,14 +44,13 @@ class TestNewlineToBr(doctest.DocTestCase):
True
"""
def
test_newline_to_br_tainted
(
self
):
"""
>>> text = '''
... <li>line one</li>
... <li>line two</li>
... '''
>>> from
ZPublisher
.TaintedString import TaintedString
>>> from
Shared
.TaintedString import TaintedString
>>> tainted = TaintedString(text)
>>> print DT_Var.newline_to_br(tainted)
<br />
...
...
src/Shared/TaintedString/__init__.py
0 → 100644
View file @
268fd5a9
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
""" TaintedString implementation.
TaintedStrings hold potentially dangerous untrusted data; anything that could
possibly hold HTML is considered dangerous. DTML code will use the quoted
value of this string, and raised exceptions in Zope will use the repr()
conversion.
$Id$
"""
from
cgi
import
escape
class
TaintedString
:
def
__init__
(
self
,
value
):
self
.
_value
=
value
def
__str__
(
self
):
return
self
.
_value
def
__repr__
(
self
):
return
repr
(
self
.
quoted
())
def
__cmp__
(
self
,
o
):
return
cmp
(
self
.
_value
,
o
)
def
__hash__
(
self
):
return
hash
(
self
.
_value
)
def
__len__
(
self
):
return
len
(
self
.
_value
)
def
__getitem__
(
self
,
index
):
v
=
self
.
_value
[
index
]
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
__getslice__
(
self
,
i
,
j
):
i
=
max
(
i
,
0
)
j
=
max
(
j
,
0
)
v
=
self
.
_value
[
i
:
j
]
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
__add__
(
self
,
o
):
return
self
.
__class__
(
self
.
_value
+
o
)
def
__radd__
(
self
,
o
):
return
self
.
__class__
(
o
+
self
.
_value
)
def
__mul__
(
self
,
o
):
return
self
.
__class__
(
self
.
_value
*
o
)
def
__rmul__
(
self
,
o
):
return
self
.
__class__
(
o
*
self
.
_value
)
def
__mod__
(
self
,
o
):
return
self
.
__class__
(
self
.
_value
%
o
)
def
__int__
(
self
):
return
int
(
self
.
_value
)
def
__float__
(
self
):
return
float
(
self
.
_value
)
def
__long__
(
self
):
return
long
(
self
.
_value
)
def
__getstate__
(
self
):
# If an object tries to store a TaintedString, it obviously wasn't aware
# that it was playing with untrusted data. Complain acordingly.
raise
SystemError
(
"A TaintedString cannot be pickled. Code that "
"caused this TaintedString to be stored should be more careful "
"with untrusted data from the REQUEST."
)
def
__getattr__
(
self
,
a
):
# for string methods support other than those defined below
return
getattr
(
self
.
_value
,
a
)
# Python 2.2 only.
def
decode
(
self
,
*
args
):
return
self
.
__class__
(
self
.
_value
.
decode
(
*
args
))
def
encode
(
self
,
*
args
):
return
self
.
__class__
(
self
.
_value
.
encode
(
*
args
))
def
expandtabs
(
self
,
*
args
):
return
self
.
__class__
(
self
.
_value
.
expandtabs
(
*
args
))
def
replace
(
self
,
*
args
):
v
=
self
.
_value
.
replace
(
*
args
)
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
split
(
self
,
*
args
):
r
=
self
.
_value
.
split
(
*
args
)
return
map
(
lambda
v
,
c
=
self
.
__class__
:
'<'
in
v
and
c
(
v
)
or
v
,
r
)
def
splitlines
(
self
,
*
args
):
r
=
self
.
_value
.
splitlines
(
*
args
)
return
map
(
lambda
v
,
c
=
self
.
__class__
:
'<'
in
v
and
c
(
v
)
or
v
,
r
)
def
translate
(
self
,
*
args
):
v
=
self
.
_value
.
translate
(
*
args
)
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
quoted
(
self
):
return
escape
(
self
.
_value
,
1
)
# As called by cDocumentTemplate
__untaint__
=
quoted
def
createSimpleWrapper
(
func
):
return
lambda
s
,
f
=
func
:
s
.
__class__
(
getattr
(
s
.
_value
,
f
)())
def
createOneArgWrapper
(
func
):
return
lambda
s
,
a
,
f
=
func
:
s
.
__class__
(
getattr
(
s
.
_value
,
f
)(
a
))
def
createOneOptArgWrapper
(
func
):
return
lambda
s
,
a
=
None
,
f
=
func
:
s
.
__class__
(
getattr
(
s
.
_value
,
f
)(
a
))
simpleWrappedMethods
=
\
"capitalize lower swapcase title upper"
.
split
()
oneArgWrappedMethods
=
"center join ljust rjust"
.
split
()
oneOptArgWrappedMethods
=
"lstrip rstrip strip"
.
split
()
for
f
in
simpleWrappedMethods
:
setattr
(
TaintedString
,
f
,
createSimpleWrapper
(
f
))
for
f
in
oneArgWrappedMethods
:
setattr
(
TaintedString
,
f
,
createOneArgWrapper
(
f
))
for
f
in
oneOptArgWrappedMethods
:
setattr
(
TaintedString
,
f
,
createOneOptArgWrapper
(
f
))
src/
ZPublisher/tests/testTaintedString
.py
→
src/
Shared/TaintedString/tests
.py
View file @
268fd5a9
...
...
@@ -7,20 +7,25 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
# FOR A PARTICULAR PURPOSE
.
#
##############################################################################
""" TaintedString tests.
$Id$
"""
import
unittest
class
TestTaintedString
(
unittest
.
TestCase
):
def
setUp
(
self
):
self
.
unquoted
=
'<test attr="&">'
self
.
quoted
=
'<test attr="&">'
self
.
tainted
=
self
.
_getClass
()(
self
.
unquoted
)
def
_getClass
(
self
):
from
ZPublisher
.TaintedString
import
TaintedString
from
Shared
.TaintedString
import
TaintedString
return
TaintedString
def
testStr
(
self
):
...
...
@@ -152,21 +157,8 @@ class TestTaintedString(unittest.TestCase):
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
TestTaintedString
,
'test'
))
suite
.
addTest
(
unittest
.
makeSuite
(
TestTaintedString
))
return
suite
def
main
():
unittest
.
TextTestRunner
().
run
(
test_suite
())
def
debug
():
test_suite
().
debug
()
def
pdebug
():
import
pdb
pdb
.
run
(
'debug()'
)
if
__name__
==
'__main__'
:
if
len
(
sys
.
argv
)
>
1
:
globals
()[
sys
.
argv
[
1
]]()
else
:
main
()
if
__name__
==
'__main__'
:
unittest
.
main
(
defaultTest
=
'test_suite'
)
src/ZPublisher/HTTPRequest.py
View file @
268fd5a9
...
...
@@ -38,12 +38,12 @@ from zope.interface import implements
from
zope.publisher.base
import
DebugFlags
from
zope.publisher.interfaces.browser
import
IBrowserRequest
from
Shared.TaintedString
import
TaintedString
from
ZPublisher.BaseRequest
import
BaseRequest
from
ZPublisher.BaseRequest
import
quote
from
ZPublisher.Converters
import
get_converter
from
ZPublisher.HTTPResponse
import
HTTPResponse
from
ZPublisher.maybe_lock
import
allocate_lock
from
ZPublisher.TaintedString
import
TaintedString
# Flags
SEQUENCE
=
1
...
...
src/ZPublisher/TaintedString.py
View file @
268fd5a9
...
...
@@ -7,145 +7,16 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
# FOR A PARTICULAR PURPOSE
.
#
##############################################################################
"""TaintedString legacy module.
__version__
=
'$Revision: 1.2 $'
[
11
:
-
2
]
$Id$
"""
from
cgi
import
escape
# TaintedStrings hold potentially dangerous untrusted data; anything that could
# possibly hold HTML is considered dangerous. DTML code will use the quoted
# value of this tring, and raised exceptions in Zope will use the repr()
# conversion.
class
TaintedString
:
def
__init__
(
self
,
value
):
self
.
_value
=
value
def
__str__
(
self
):
return
self
.
_value
def
__repr__
(
self
):
return
repr
(
self
.
quoted
())
def
__cmp__
(
self
,
o
):
return
cmp
(
self
.
_value
,
o
)
def
__hash__
(
self
):
return
hash
(
self
.
_value
)
def
__len__
(
self
):
return
len
(
self
.
_value
)
def
__getitem__
(
self
,
index
):
v
=
self
.
_value
[
index
]
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
__getslice__
(
self
,
i
,
j
):
i
=
max
(
i
,
0
)
j
=
max
(
j
,
0
)
v
=
self
.
_value
[
i
:
j
]
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
__add__
(
self
,
o
):
return
self
.
__class__
(
self
.
_value
+
o
)
def
__radd__
(
self
,
o
):
return
self
.
__class__
(
o
+
self
.
_value
)
def
__mul__
(
self
,
o
):
return
self
.
__class__
(
self
.
_value
*
o
)
def
__rmul__
(
self
,
o
):
return
self
.
__class__
(
o
*
self
.
_value
)
def
__mod__
(
self
,
o
):
return
self
.
__class__
(
self
.
_value
%
o
)
def
__int__
(
self
):
return
int
(
self
.
_value
)
def
__float__
(
self
):
return
float
(
self
.
_value
)
def
__long__
(
self
):
return
long
(
self
.
_value
)
def
__getstate__
(
self
):
# If an object tries to store a TaintedString, it obviously wasn't aware
# that it was playing with untrusted data. Complain acordingly.
raise
SystemError
(
"A TaintedString cannot be pickled. Code that "
"caused this TaintedString to be stored should be more careful "
"with untrusted data from the REQUEST."
)
def
__getattr__
(
self
,
a
):
# for string methods support other than those defined below
return
getattr
(
self
.
_value
,
a
)
# Python 2.2 only.
def
decode
(
self
,
*
args
):
return
self
.
__class__
(
self
.
_value
.
decode
(
*
args
))
def
encode
(
self
,
*
args
):
return
self
.
__class__
(
self
.
_value
.
encode
(
*
args
))
def
expandtabs
(
self
,
*
args
):
return
self
.
__class__
(
self
.
_value
.
expandtabs
(
*
args
))
def
replace
(
self
,
*
args
):
v
=
self
.
_value
.
replace
(
*
args
)
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
split
(
self
,
*
args
):
r
=
self
.
_value
.
split
(
*
args
)
return
map
(
lambda
v
,
c
=
self
.
__class__
:
'<'
in
v
and
c
(
v
)
or
v
,
r
)
def
splitlines
(
self
,
*
args
):
r
=
self
.
_value
.
splitlines
(
*
args
)
return
map
(
lambda
v
,
c
=
self
.
__class__
:
'<'
in
v
and
c
(
v
)
or
v
,
r
)
def
translate
(
self
,
*
args
):
v
=
self
.
_value
.
translate
(
*
args
)
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
quoted
(
self
):
return
escape
(
self
.
_value
,
1
)
# As called by cDocumentTemplate
__untaint__
=
quoted
def
createSimpleWrapper
(
func
):
return
lambda
s
,
f
=
func
:
s
.
__class__
(
getattr
(
s
.
_value
,
f
)())
def
createOneArgWrapper
(
func
):
return
lambda
s
,
a
,
f
=
func
:
s
.
__class__
(
getattr
(
s
.
_value
,
f
)(
a
))
def
createOneOptArgWrapper
(
func
):
return
lambda
s
,
a
=
None
,
f
=
func
:
s
.
__class__
(
getattr
(
s
.
_value
,
f
)(
a
))
simpleWrappedMethods
=
\
"capitalize lower swapcase title upper"
.
split
()
oneArgWrappedMethods
=
"center join ljust rjust"
.
split
()
oneOptArgWrappedMethods
=
"lstrip rstrip strip"
.
split
()
for
f
in
simpleWrappedMethods
:
setattr
(
TaintedString
,
f
,
createSimpleWrapper
(
f
))
for
f
in
oneArgWrappedMethods
:
setattr
(
TaintedString
,
f
,
createOneArgWrapper
(
f
))
for
f
in
oneOptArgWrappedMethods
:
setattr
(
TaintedString
,
f
,
createOneOptArgWrapper
(
f
))
from
zope.deferredimport
import
deprecated
deprecated
(
'ZPublisher.TaintedString will be removed in Zope 2.14. Please '
'import from Shared.TaintedString instead.'
,
TaintedString
=
'Shared.TaintedString:TaintedString'
,
)
src/ZPublisher/tests/testHTTPRequest.py
View file @
268fd5a9
...
...
@@ -71,7 +71,7 @@ class HTTPRequestTests(unittest.TestCase):
# Also raises an Assertion if a string which *should* have been
# tainted is found, or when a tainted string is not deemed dangerous.
from
ZPublisher.HTTPRequest
import
record
from
ZPublisher
.TaintedString
import
TaintedString
from
Shared
.TaintedString
import
TaintedString
retval
=
0
...
...
@@ -1015,8 +1015,12 @@ test %s
'''
%
(
'test'
*
1000
)
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
RecordTests
,
'test'
))
suite
.
addTest
(
unittest
.
makeSuite
(
HTTPRequestTests
,
'test'
))
suite
.
addTest
(
unittest
.
makeSuite
(
RecordTests
))
suite
.
addTest
(
unittest
.
makeSuite
(
HTTPRequestTests
))
return
suite
if
__name__
==
'__main__'
:
unittest
.
main
(
defaultTest
=
'test_suite'
)
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