Repository: yt-dlp/yt-dlp
File: yt_dlp/utils.py (Python)

Code before:
        html, escape_value=False)


def get_elements_by_attribute(*args, **kwargs):
    """Return the content of the tag with the specified attribute in the passed HTML document"""
    return [content for content, _ in get_elements_text_and_html_by_attribute(*args, **kwargs)]


def get_elements_html_by_attribute(*args, **kwargs):
    """Return the html of the tag with the specified attribute in the passed HTML document"""
    return [whole for _, whole in get_elements_text_and_html_by_attribute(*args, **kwargs)]


def get_elements_text_and_html_by_attribute(attribute, value, html, escape_value=True):
    """
    Return the text (content) and the html (whole) of the tag with the specified
    attribute in the passed HTML document
    """

    value_quote_optional = '' if re.match(r'''[\s"'`=<>]''', value) else r'?'

    value = re.escape(value) if escape_value else value

    partial_element_re = \
        r'''<(?P<tag>[a-zA-Z0-9:._-]+)(?:\s+[a-zA-Z0-9_:.-]+(?:=[^\s"'`=<>]+|=(?:"[^"]*"|'[^']*')|))*?\s+%(attribute)s=(?P<_q>['"]%(vqo)s)%(value)s(?P=_q)''' % \
        {'attribute': re.escape(attribute), 'value': value, 'vqo': value_quote_optional}

    for m in re.finditer(partial_element_re, html):
        content, whole = get_element_text_and_html_by_tag(m.group('tag'), html[m.start():])

        yield unescapeHTML(re.sub(r'^(?P<q>["\'])(?P<content>.*)(?P=q)$', r'\g<content>', content, flags=re.DOTALL)), \
            whole


class HTMLBreakOnClosingTagParser(compat_HTMLParser):
    """
    HTML parser which raises HTMLBreakOnClosingTagException upon reaching the
    closing tag for the first opening tag it has encountered, and can be used
    as a context manager
    """

    class HTMLBreakOnClosingTagException(Exception):
        pass

    def __init__(self):
        self.tagstack = collections.deque()
        compat_HTMLParser.__init__(self)

    def __enter__(self):
        return self


Review comment (security):
Would this not work?
```suggestion
    # Do not use re.verbose since value may contain unescaped spaces
    partial_element_re = (
        r'''<(?P<tag>[a-zA-Z0-9:._-]+)(?:\s(?:[^>"']|"[^"]*"|'[^']*')*)?\s%(attribute)s\s*=\s*(?P<_q>['"]%(vqo)s)(?:%(value)s)(?P=_q)'''
        % {'attribute': re.escape(attribute), 'value': value, 'vqo': value_quote_optional})
```
It is simpler than your regex, passes all tests and should not cause any catastrophic backtracking as far as I can tell (since the `|` groups are mutually exclusive and there is no non-greedy matching)

Code after:
        html, escape_value=False)


def get_elements_by_attribute(*args, **kwargs):
    """Return the content of the tag with the specified attribute in the passed HTML document"""
    return [content for content, _ in get_elements_text_and_html_by_attribute(*args, **kwargs)]


def get_elements_html_by_attribute(*args, **kwargs):
    """Return the html of the tag with the specified attribute in the passed HTML document"""
    return [whole for _, whole in get_elements_text_and_html_by_attribute(*args, **kwargs)]


def get_elements_text_and_html_by_attribute(attribute, value, html, escape_value=True):
    """
    Return the text (content) and the html (whole) of the tag with the specified
    attribute in the passed HTML document
    """

    value_quote_optional = '' if re.match(r'''[\s"'`=<>]''', value) else '?'

    value = re.escape(value) if escape_value else value

    partial_element_re = r'''(?x)
        <(?P<tag>[a-zA-Z0-9:._-]+)
         (?:\s(?:[^>"']|"[^"]*"|'[^']*')*)?
         \s%(attribute)s\s*=\s*(?P<_q>['"]%(vqo)s)(?-x:%(value)s)(?P=_q)
        ''' % {'attribute': re.escape(attribute), 'value': value, 'vqo': value_quote_optional}

    for m in re.finditer(partial_element_re, html):
        content, whole = get_element_text_and_html_by_tag(m.group('tag'), html[m.start():])

        yield (
            unescapeHTML(re.sub(r'^(?P<q>["\'])(?P<content>.*)(?P=q)$', r'\g<content>', content, flags=re.DOTALL)),
            whole
        )


class HTMLBreakOnClosingTagParser(compat_HTMLParser):
    """
    HTML parser which raises HTMLBreakOnClosingTagException upon reaching the
    closing tag for the first opening tag it has encountered, and can be used
    as a context manager
    """

    class HTMLBreakOnClosingTagException(Exception):
        pass

    def __init__(self):
        self.tagstack = collections.deque()
        compat_HTMLParser.__init__(self)