    def traverse(cls, base, request, path_items):
        """See ``zope.app.pagetemplate.engine``."""

        validate = getSecurityManager().validate
        path_items = list(path_items)
        path_items.reverse()

        while path_items:
            name = path_items.pop()

            if ITraversable.providedBy(base):
                base = getattr(base, cls.traverse_method)(name)
            else:
                found = traversePathElement(base, name, path_items,
                                            request=request)

                # If traverse_method is something other than
                # ``restrictedTraverse`` then traversal is assumed to be
                # unrestricted. This emulates ``unrestrictedTraverse``
                if cls.traverse_method != 'restrictedTraverse':
                    base = found
                    continue

                # Special backwards compatibility exception for the name ``_``,
                # which was often used for translation message factories.
                # Allow and continue traversal.
                if name == '_':
                    warnings.warn('Traversing to the name `_` is deprecated '
                                  'and will be removed in Zope 6.',
                                  DeprecationWarning)
                    base = found
                    continue

                # All other names starting with ``_`` are disallowed.
                # This emulates what restrictedTraverse does.
                if name.startswith('_'):
                    raise NotFound(name)

                # traversePathElement doesn't apply any Zope security policy,
                # so we validate access explicitly here.
                try:
                    validate(base, base, name, found)
                    base = found
                except Unauthorized:
                    # Convert Unauthorized to prevent information disclosures
                    raise NotFound(name)

        return base
The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.