diff --git a/CHANGES.rst b/CHANGES.rst index 9ceb092a46..2d2b8e6ed4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,7 +14,10 @@ https://github.com/zopefoundation/Zope/blob/4.x/CHANGES.rst - Update to newest compatible versions of dependencies. -- Added CC-BY 4.0 license to the Zope logo. +- Added CC-BY 4.0 license to the Zope logo. + +- Fix ``IndexError`` on traversal past the root using `..`. + (`#1218 `_) 5.10 (2024-05-18) diff --git a/src/ZPublisher/BaseRequest.py b/src/ZPublisher/BaseRequest.py index ab8382cbbd..3158ba3267 100644 --- a/src/ZPublisher/BaseRequest.py +++ b/src/ZPublisher/BaseRequest.py @@ -366,6 +366,8 @@ def traverse(self, path, response=None, validated_hook=None): if not item or item == '.': continue elif item == '..': + if not len(clean): + return response.notFoundError(path) del clean[-1] else: clean.append(item) diff --git a/src/ZPublisher/tests/testBaseRequest.py b/src/ZPublisher/tests/testBaseRequest.py index a4b7665bf8..91986a838e 100644 --- a/src/ZPublisher/tests/testBaseRequest.py +++ b/src/ZPublisher/tests/testBaseRequest.py @@ -373,6 +373,18 @@ def test_traverse_slash(self): self.assertEqual(r.URL, '/index_html') self.assertEqual(r.response.base, '') + def test_traverse_special_names(self): + root, folder = self._makeRootAndFolder() + r = self._makeOne(root) + self.assertRaises(NotFound, r.traverse, 'REQUEST') + self.assertRaises(NotFound, r.traverse, 'aq_self') + self.assertRaises(NotFound, r.traverse, 'aq_base') + + def test_traverse_past_root(self): + root, folder = self._makeRootAndFolder() + r = self._makeOne(root) + self.assertRaises(NotFound, r.traverse, '..') + def test_traverse_attribute_with_docstring(self, use_docstring=None): root, folder = self._makeRootAndFolder() folder._setObject('objBasic', self._makeBasicObject(use_docstring))