Commit f7e38c41 authored by Andreas Jung's avatar Andreas Jung

Monkey patch for LP #257276

This code is taken from the encodings module of Python 2.4.
Note that this code is originally (C) CNRI and it is possibly not compatible
with the ZPL and therefore should not live within svn.zope.org. However this
checkin is blessed by Jim Fulton for now. The fix is no longer required with
Python 2.5 and hopefully fixed in Python 2.4.6 release.
parent 3753d1a2
......@@ -204,6 +204,10 @@ Zope Changes
Bugs Fixed
- Launchpad #257276: fix for possible denial-of-service attack
in PythonScript when passing an arbitrary module to the encode()
or decode() of strings.
- Launchpad #257269: 'raise SystemExit' with a PythonScript could shutdown
a complete Zope instance
......
......@@ -61,3 +61,100 @@ def recompile(self):
if names:
return 'The following Scripts were recompiled:\n' + '\n'.join(names)
return 'No Scripts were found that required recompilation.'
# Monkey patch for LP #257276
# This code is taken from the encodings module of Python 2.4.
# Note that this code is originally (C) CNRI and it is possibly not compatible
# with the ZPL and therefore should not live within svn.zope.org. However this
# checkin is blessed by Jim Fulton for now. The fix is no longer required with
# Python 2.5 and hopefully fixed in Python 2.4.6 release.
def search_function(encoding):
# Cache lookup
entry = _cache.get(encoding, _unknown)
if entry is not _unknown:
return entry
# Import the module:
#
# First try to find an alias for the normalized encoding
# name and lookup the module using the aliased name, then try to
# lookup the module using the standard import scheme, i.e. first
# try in the encodings package, then at top-level.
#
norm_encoding = normalize_encoding(encoding)
aliased_encoding = _aliases.get(norm_encoding) or \
_aliases.get(norm_encoding.replace('.', '_'))
if aliased_encoding is not None:
modnames = [aliased_encoding,
norm_encoding]
else:
modnames = [norm_encoding]
for modname in modnames:
if not modname or '.' in modname:
continue
try:
mod = __import__(modname,
globals(), locals(), _import_tail)
if not mod.__name__.startswith('encodings.'):
continue
except ImportError:
pass
else:
break
else:
mod = None
try:
getregentry = mod.getregentry
except AttributeError:
# Not a codec module
mod = None
if mod is None:
# Cache misses
_cache[encoding] = None
return None
# Now ask the module for the registry entry
entry = tuple(getregentry())
if len(entry) != 4:
raise CodecRegistryError,\
'module "%s" (%s) failed to register' % \
(mod.__name__, mod.__file__)
for obj in entry:
if not callable(obj):
raise CodecRegistryError,\
'incompatible codecs in module "%s" (%s)' % \
(mod.__name__, mod.__file__)
# Cache the codec registry entry
_cache[encoding] = entry
# Register its aliases (without overwriting previously registered
# aliases)
try:
codecaliases = mod.getaliases()
except AttributeError:
pass
else:
for alias in codecaliases:
if not _aliases.has_key(alias):
_aliases[alias] = modname
# Return the registry entry
return entry
# MONKEY
import encodings
encodings.search_function.func_code = search_function.func_code
......@@ -226,6 +226,9 @@ class TestPythonScriptNoAq(PythonScriptTestBase):
ps = self._newPS("raise SystemExit")
self.assertRaises(ValueError, ps)
def testEncodingTestDotTestAllLaunchpad257276(self):
ps = self._newPS("return 'foo'.encode('test.testall')")
self.assertRaises(LookupError, ps)
class TestPythonScriptErrors(PythonScriptTestBase):
......
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