[Zope-CVS] CVS: Products/Hotfix-20040714 - README.txt:1.1 __init__.py:1.1 version.txt:1.1

Fred L. Drake, Jr. fdrake at gmail.com
Mon Aug 9 11:56:36 EDT 2004


Update of /cvs-repository/Products/Hotfix-20040714
In directory cvs.zope.org:/tmp/cvs-serv16351

Added Files:
	README.txt __init__.py version.txt 
Log Message:
Save for all eternity the TAL hotfix provided for Zope 2.7.0 and 2.7.1.


=== Added File Products/Hotfix-20040714/README.txt ===
Zope Hotfix Release, 2004/07/14

  Overview

    This hotfix product fixes a security bug in Page Templates.  This
    fix ensures that values substituted in named slots in translated
    elements are properly encoded.  If encoding is not desired and the
    source of the replacement text is trusted, the "structure"
    modifier can be used with the tal:content or tal:replace attribute
    to explicitly disable encoding.


  Affected Versions

    This fix applies to Zope 2.7.0 and 2.7.1.  Zope versions 2.7.2 and
    newer already contain this fix, and do not require this hotfix.

    This fix also obsoletes 'Hotfix_20040713', so that should be
    uninstalled when this hotfix is installed.  See the README.txt
    file provided with 'Hotfix_20040713' for instructions on
    removing that hotfix.


  Installing the Hotfix

    1. Be sure to uninstall 'Hotfix_20040713' if it is installed.

    2. Unpack the tarball into a working directory, and then move or
       link the 'Hotfix_20040714' directory into the Products
       directory of your '$INSTANCE_HOME'.

    3. Restart Zope.

    Windows users should unzip the ZIP file and move the extracted
    'Hotfix_20040714' folder to their Zope's 'Products' folder.


  Uninstalling the Hotfix
  
    You may remove the 'Hotfix_20040714' product directory after
    upgrading to one of the updated versions of Zope (2.7.2 or later).

    For example::

      $ cd /var/zope/instance/Products
      $ rm -r Hotfix_20040714


=== Added File Products/Hotfix-20040714/__init__.py ===
##############################################################################
#
# Copyright (c) 2004 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.
#
##############################################################################
"""Hotfix_20040714 product.

$Id: __init__.py,v 1.1 2004/08/09 15:56:35 fdrake Exp $
"""
import cgi

from TAL import TALDefs
from TAL import TALGenerator
from TAL import TALInterpreter

import zLOG


# for TALGenerator
def _tal_1_5_emitI18nVariable(self, stuff):
    # Used for i18n:name attributes.  arg is extra information describing
    # how the contents of the variable should get filled in, and it will
    # either be a 1-tuple or a 2-tuple.  If arg[0] is None, then the
    # i18n:name value is taken implicitly from the contents of the tag,
    # e.g. "I live in <span i18n:name="country">the USA</span>".  In this
    # case, arg[1] is the opcode sub-program describing the contents of
    # the tag.
    #
    # When arg[0] is not None, it contains the tal expression used to
    # calculate the contents of the variable, e.g.
    # "I live in <span i18n:name="country"
    #                  tal:replace="here/countryOfOrigin" />"
    varname, action, expression = stuff
    m = TALGenerator._name_rx.match(varname)
    if m is None or m.group() != varname:
        raise TALDefs.TALError("illegal i18n:name: %r"
                               % varname, self.position)
    key = cexpr = None
    program = self.popProgram()
    if action == TALGenerator.I18N_REPLACE:
        # This is a tag with an i18n:name and a tal:replace (implicit or
        # explicit).  Get rid of the first and last elements of the
        # program, which are the start and end tag opcodes of the tag.
        program = program[1:-1]
    elif action == TALGenerator.I18N_CONTENT:
        # This is a tag with an i18n:name and a tal:content
        # (explicit-only).  Keep the first and last elements of the
        # program, so we keep the start and end tag output.
        pass
    else:
        assert action == TALGenerator.I18N_EXPRESSION
        key, expr = TALDefs.parseSubstitution(expression)
        cexpr = self.compileExpression(expr)
    self.emit('i18nVariable',
              varname, program, cexpr, int(key == "structure"))


# for TALInterpreter
def _tal_1_5_do_i18nVariable(self, stuff):
    varname, program, expression, structure = stuff
    if expression is None:
        # The value is implicitly the contents of this tag, so we have to
        # evaluate the mini-program to get the value of the variable.
        state = self.saveState()
        try:
            # use the same StringIO as the rest of TALInterpreter
            tmpstream = TALInterpreter.StringIO()
            self.interpretWithStream(program, tmpstream)
            value = TALInterpreter.normalize(tmpstream.getvalue())
        finally:
            self.restoreState(state)
    else:
        # Evaluate the value to be associated with the variable in the
        # i18n interpolation dictionary.
        if structure:
            value = self.engine.evaluateStructure(expression)
        else:
            value = self.engine.evaluate(expression)

        if not structure:
            value = cgi.escape(str(value))

    # Either the i18n:name tag is nested inside an i18n:translate in which
    # case the last item on the stack has the i18n dictionary and string
    # representation, or the i18n:name and i18n:translate attributes are
    # in the same tag, in which case the i18nStack will be empty.  In that
    # case we can just output the ${name} to the stream
    i18ndict, srepr = self.i18nStack[-1]
    i18ndict[varname] = value
    placeholder = '${%s}' % varname
    srepr.append(placeholder)
    self._stream_write(placeholder)


def initialize(context):
    # Patch the bytecode version:
    TALDefs.TAL_VERSION = "1.5"
    TALGenerator.TAL_VERSION = TALDefs.TAL_VERSION
    import TAL.TALInterpreter
    TAL.TALInterpreter.TAL_VERSION = TALDefs.TAL_VERSION

    # Patch the code generator:
    TALGenerator.TALGenerator.emitI18nVariable = _tal_1_5_emitI18nVariable

    # Patch the interpreter:
    from TAL.TALInterpreter import TALInterpreter
    do_i18nVariable = _tal_1_5_do_i18nVariable
    TALInterpreter.do_i18nVariable = do_i18nVariable
    TALInterpreter.bytecode_handlers["i18nVariable"] = do_i18nVariable
    TALInterpreter.bytecode_handlers_tal["i18nVariable"] = do_i18nVariable
    zLOG.LOG("Hotfix_20040714", zLOG.INFO,
             "Monkey patched TAL to properly encode replacements in"
             " translated text.")


=== Added File Products/Hotfix-20040714/version.txt ===
20040714



More information about the Zope-CVS mailing list