Ticket #13728 (new Bug)
Opened 3 years ago
Using Unicode TALES string: expressions cause KeyError: 'context'
Reported by: | davidjb | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | 4.x |
Component: | Unknown | Version: | |
Keywords: | Cc: |
Description
When trying to use a TALES string: expression, a KeyError is produced because the resulting expression context doesn't appear to have the required keys. Specifically, problematic expressions appear to be limited to those prefixed with "string:", for example:
u'string:${portal_url}' u'string:${portal_url}/foobar'
This only causes an issue when the TALES expression is Unicode. Switching the above to byte strings produces to no issue. This isn't a solution, however, as submissions off forms (such as the ones being received in plone.app.contentrules) will likely be Unicode.
To reproduce:
from Products.CMFPlone.utils import getToolByName from Products.CMFCore.Expression import Expression, createExprContext portal_url = getToolByName(context, 'portal_url') portal = portal_url.getPortalObject() ec = createExprContext(context, portal, None) expr = Expression(u'string:${portal_url}/foobar') #Fails with ``KeyError: 'context'`` because ec.contexts['context'] is misssing print expr(ec) #Succeeds in outputting URL expr = Expression('string:${portal_url}') print expr(ec)
My thinking is that the problem is either with Products.CMFCore.Expression.createExprContext not adding enough into the contexts dictionary or a problem with the Products.PageTemplates.Expressions.ZopeContext._handleText (line 250) function expecting incorrect keys. It's worth noting that if a UnicodeDecodeError happens in that latter function, it expects a 'template' key to be present within the expression context as well -- something else that is missing.
I've worked around this issue for using TALES in plone.app.contentrules temporarily (in https://github.com/plone/plone.app.contentrules/commit/f825dd9ffb6c434bd41c33219bc77e6f06c96bea) but the issue would affect any caller attempting to work with such an expression in the rest of Plone.
Example traceback from plone.app.contentrules:
Traceback (innermost last): Module ZPublisher.Publish, line 60, in publish Module ZPublisher.mapply, line 77, in mapply Module ZPublisher.Publish, line 46, in call_object Module plone.z3cform.layout, line 66, in __call__ Module plone.z3cform.layout, line 50, in update Module plone.dexterity.browser.add, line 112, in update Module plone.z3cform.fieldsets.extensible, line 59, in update Module plone.z3cform.patch, line 30, in GroupForm_update Module z3c.form.group, line 141, in update Module plone.app.z3cform.csrf, line 21, in execute Module z3c.form.action, line 98, in execute Module z3c.form.button, line 315, in __call__ Module z3c.form.button, line 170, in __call__ Module plone.dexterity.browser.add, line 99, in handleAdd Module z3c.form.form, line 247, in createAndAdd Module plone.dexterity.browser.add, line 78, in add Module plone.dexterity.utils, line 167, in addContentToContainer Module OFS.ObjectManager, line 358, in _setObject Module zope.event, line 31, in notify Module zope.component.event, line 24, in dispatch Module zope.component._api, line 136, in subscribers Module zope.component.registry, line 321, in subscribers Module zope.interface.adapter, line 585, in subscribers Module plone.app.contentrules.handlers, line 179, in added Module plone.app.contentrules.handlers, line 118, in execute Module plone.contentrules.engine.executor, line 27, in __call__ Module plone.contentrules.rule.rule, line 44, in __call__ Module plone.app.contentrules.conditions.talesexpression, line 63, in __call__ Module Products.CMFCore.Expression, line 47, in __call__ Module Products.PageTemplates.Expressions, line 383, in __call__ Module Products.PageTemplates.Expressions, line 226, in evaluateText Module Products.PageTemplates.Expressions, line 250, in _handleText KeyError: 'context'