Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adopt_user fills the AccessControl context-stack and leads to "SystemError: Excessive recursion" #419

Open
jensens opened this issue Nov 7, 2018 · 0 comments

Comments

@jensens
Copy link
Sponsor Member

jensens commented Nov 7, 2018

I hit this with an import/sync script, where we call the plone.api.env.adopt_user several times. So, it was more than 100 times.

Traceback (most recent call last):
  File "/data/eggs/Zope2-2.13.27-py2.7.egg/OFS/SimpleItem.py", line 242, in raise_standardErrorMessage
    v = s(**kwargs)
  File "/data/eggs/Products.CMFCore-2.2.10-py2.7.egg/Products/CMFCore/FSPythonScript.py", line 127, in __call__
    return Script.__call__(self, *args, **kw)
  File "/data/eggs/Zope2-2.13.27-py2.7.egg/Shared/DC/Scripts/Bindings.py", line 322, in __call__
    return self._bindAndExec(args, kw, None)
  File "/data/eggs/Zope2-2.13.27-py2.7.egg/Shared/DC/Scripts/Bindings.py", line 351, in _bindAndExec
    security.addContext(self)
  File "/data/eggs/AccessControl-3.0.11-py2.7-linux-x86_64.egg/AccessControl/ImplPython.py", line 603, in addContext
    raise SystemError, 'Excessive recursion'
SystemError: Excessive recursion

adopt_user is a context manager. On __enter__ it gets the current security-manager, remembers it, creates a newSecurityManager and sets it. On __exit__ it sets back to the old security-manager.

Now, if a new SecurityManager is created all is fine.

But if then something is executed, that binds the new security-manager, like Shared.DC.Scripts.Bindings._bindAndExec, it calls the security-managers method addContext which holds a stack of all contexts on the current request. And this stack is limited to 100 . An environment variable Z_MAX_STACK_SIZE will override this if needed (even if the docs are telling me this would be esoteric - really!).

This is a bug, because when we set back to the old security manager, we are also responsible to clean up the context stack to its previous settings. Since the context is always the same (current request), this is logic-wise not a problem.

One solution would be to read the length of the stack and slice the lengths afterwards to its previous value.

After all, it helped to start with Z_MAX_STACK_SIZE=100000 ./bin/instance fg for me in this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant