Skip to content

Commit

Permalink
Merge 98ad1a3 into d699289
Browse files Browse the repository at this point in the history
  • Loading branch information
viktordick committed Mar 26, 2022
2 parents d699289 + 98ad1a3 commit d17dbcc
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Expand Up @@ -6,7 +6,8 @@ For changes before version 3.0, see ``HISTORY.rst``.
5.4 (unreleased)
----------------

- Nothing changed yet.
- Prevent race condition in guarded_import
(see `#123 <https://github.com/zopefoundation/AccessControl/issues/123>`_)


5.3 (2022-02-25)
Expand Down
7 changes: 6 additions & 1 deletion src/AccessControl/SecurityInfo.py
Expand Up @@ -270,7 +270,12 @@ def secureModule(mname, *imp):

if imp:
__import__(mname, *imp)
del _moduleSecurity[mname]
try:
del _moduleSecurity[mname]
except KeyError:
# In case of access from multiple threads, the del might fail, but that
# is OK.
pass
module = sys.modules[mname]
modsec.apply(module.__dict__)
_appliedModuleSecurity[mname] = modsec
Expand Down
21 changes: 21 additions & 0 deletions src/AccessControl/tests/testModuleSecurity.py
Expand Up @@ -70,6 +70,27 @@ def testPublicModule(self):
self.assertAuth('AccessControl.tests.public_module.submodule',
('pub',))

def testPublicModuleThreaded(self):
"""
Import the same module from two threads simultaneously, checking that
this does not result in a race condition.
"""
import threading
finished = []

def threaded_run():
self.assertAuth('AccessControl.tests.public_module', ())
finished.append(True)

threads = [threading.Thread(target=threaded_run) for _ in range(2)]

for t in threads:
t.start()
for t in threads:
t.join()

self.assertEqual(len(finished), 2)

def test_public_module_asterisk_not_allowed(self):
self.assertUnauth('AccessControl.tests.public_module', ('*',))

Expand Down

0 comments on commit d17dbcc

Please sign in to comment.