>>> from Products.ZCatalog.Catalog import Catalog
>>> from Products.CMFCore.CatalogTool import CatalogTool
>>> from DateTime.DateTime import DateTime
>>> from pprint import pprint as pp
>>>
>>> def trace(f):
... """decorator to trace the effectively executed query."""
... f = getattr(f, "__func__", f)
... def traced(*args, **kw):
... r = f(*args, **kw)
... print("effective query:")
... pp(r)
... return r
... return traced
...
>>> # intrument `Catalog.merge_query_args` to see what happens
>>> Catalog.merge_query_args = trace(Catalog.merge_query_args)
>>>
>>> c = CatalogTool()
>>>
>>> def check(REQUEST=None, **kw):
... try:
... c(REQUEST, **kw)
... except Exception: pass # we are not really interested in the result
...
>>> dt = DateTime(0)
>>>
>>> # this works correctly
>>> check(effective=dict(query=dt, range="max"))
effective query:
{'allowedRolesAndUsers': ['Anonymous', 'Anonymous', 'user:None'],
'effective': {'query': DateTime('1970/01/01 01:00:00 GMT+1'), 'range': 'max'},
'expires': {'query': DateTime('2019/03/15 18:23:9.599377 GMT+1'),
'range': 'min'}}
>>>
>>> # this should be equivalent - but is not:
>>> # the `effective` subquery is more permissive than it should be
>>> check(dict(effective=dict(query=dt, range="max")))
effective query:
{'allowedRolesAndUsers': ['Anonymous', 'Anonymous', 'user:None'],
'effective': {'query': DateTime('2019/03/15 18:23:40.451992 GMT+1'),
'range': 'max'},
'expires': {'query': DateTime('2019/03/15 18:23:40.451992 GMT+1'),
'range': 'min'}}
For unpriviledged users,
CatalogTool.searchResultsrewrites the base query to add additional restrictions. But it is not careful enough: the restricted query can be more permissive than the unrestricted one -- potentially resulting in too many hits. Potentially affected are base queries withexpires,effectiveorallowedRolesAndUserssubqueries. Forexpiresandeffectivesubqueries the problem occurs only when they are not specified by keyword arguments (but in theREQUESTargument). The following example demontrates the problem: