Commit 149a696b authored by Hanno Schlichting's avatar Hanno Schlichting

Moved ``TaintedString`` into the new AccessControl.tainted module.

parent be86c7e0
......@@ -11,6 +11,8 @@ Trunk (unreleased)
Restructuring
+++++++++++++
- Moved ``TaintedString`` into the new AccessControl.tainted module.
- Moved the ``zExceptions`` package into its own distribution.
- Completely refactored ``ZPublisher.WSGIResponse`` in order to provide
......
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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.
"""
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"]
oneArgWrappedMethods = ["center", "join", "ljust", "rjust"]
oneOptArgWrappedMethods = ["lstrip", "rstrip", "strip"]
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))
......@@ -11,8 +11,6 @@
#
##############################################################################
""" TaintedString tests.
$Id$
"""
import unittest
......@@ -25,7 +23,7 @@ class TestTaintedString(unittest.TestCase):
self.tainted = self._getClass()(self.unquoted)
def _getClass(self):
from Shared.TaintedString import TaintedString
from AccessControl.tainted import TaintedString
return TaintedString
def testStr(self):
......@@ -159,6 +157,3 @@ def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestTaintedString))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
......@@ -31,7 +31,7 @@ from RestrictedPython.Guards import safe_builtins
from RestrictedPython.Utilities import utility_builtins
from RestrictedPython.Eval import RestrictionCapableEval
from Shared.TaintedString import TaintedString
from AccessControl.tainted import TaintedString
test = utility_builtins['test'] # for backwards compatibility, dont remove!
......
......@@ -160,7 +160,7 @@ from DocumentTemplate.html_quote import html_quote
from DocumentTemplate.DT_Util import parse_params, name_param, str, ustr
from Acquisition import aq_base
from Shared.TaintedString import TaintedString
from AccessControl.tainted import TaintedString
from zope.structuredtext.html import HTML
from zope.structuredtext.document import DocumentWithImages
from App.config import getConfiguration
......
......@@ -51,7 +51,7 @@ class TestNewlineToBr(doctest.DocTestCase):
... <li>line one</li>
... <li>line two</li>
... '''
>>> from Shared.TaintedString import TaintedString
>>> from AccessControl.tainted import TaintedString
>>> tainted = TaintedString(text)
>>> print DT_Var.newline_to_br(tainted)
<br />
......
......@@ -29,12 +29,12 @@ from AccessControl.Permissions import view as View
from AccessControl.Permissions import ftp_access
from AccessControl.DTML import RestrictedDTML
from AccessControl.requestmethod import requestmethod
from AccessControl.tainted import TaintedString
from OFS.Cache import Cacheable
from OFS.History import Historical
from OFS.History import html_diff
from OFS.SimpleItem import Item_w__name__
from OFS.ZDOM import ElementWithTitle
from Shared.TaintedString import TaintedString
from webdav.Lockable import ResourceLockedError
from zExceptions import Forbidden
from zExceptions.TracebackSupplement import PathTracebackSupplement
......
......@@ -44,7 +44,7 @@ class TestItem(unittest.TestCase):
self.failUnless('full details: testing' in value.message)
def test_raise_StandardErrorMessage_TaintedString_errorValue(self):
from Shared.TaintedString import TaintedString
from AccessControl.tainted import TaintedString
class REQUEST(object):
class RESPONSE(object):
handle_errors = True
......
......@@ -15,7 +15,7 @@ class DTMLMethodTests(unittest.TestCase):
verifyClass(IWriteLock, self._getTargetClass())
def test_edit_taintedstring(self):
from Shared.TaintedString import TaintedString
from AccessControl.tainted import TaintedString
doc = self._makeOne()
self.assertEquals(doc.read(), '')
data = TaintedString('hello<br/>')
......
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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))
from zope.deferredimport import deprecated
deprecated('Shared.TaintedString will be removed in Zope 2.14. Please '
'import from AccessControl.tainted instead.',
TaintedString = 'AccessControl.tainted:TaintedString',
createSimpleWrapper = 'AccessControl.tainted:createSimpleWrapper',
createOneArgWrapper = 'AccessControl.tainted:createOneArgWrapper',
createOneOptArgWrapper = 'AccessControl.tainted:createOneOptArgWrapper',
)
......@@ -38,7 +38,7 @@ from zope.interface import implements
from zope.publisher.base import DebugFlags
from zope.publisher.interfaces.browser import IBrowserRequest
from Shared.TaintedString import TaintedString
from AccessControl.tainted import TaintedString
from ZPublisher.BaseRequest import BaseRequest
from ZPublisher.BaseRequest import quote
from ZPublisher.Converters import get_converter
......
......@@ -11,12 +11,10 @@
#
##############################################################################
"""TaintedString legacy module.
$Id$
"""
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',
'import from AccessControl.tainted instead.',
TaintedString = 'AccessControl.tainted:TaintedString',
)
......@@ -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 Shared.TaintedString import TaintedString
from AccessControl.tainted import TaintedString
retval = 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment