From 92b658c95651f3c9504fd42e1a69107d09d03f87 Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Thu, 29 Jun 2006 00:52:32 +0000 Subject: [PATCH] SF bug #1504333: sgmlib should allow angle brackets in quoted values (modified patch by Sam Ruby; changed to use separate REs for start and end tags to reduce matching cost for end tags; extended tests; updated to avoid breaking previous changes to support IPv6 addresses in unquoted attribute values) --- Lib/sgmllib.py | 16 ++++++++++------ Lib/test/test_sgmllib.py | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/Lib/sgmllib.py b/Lib/sgmllib.py index 634c837605c6..9dea205a7695 100644 --- a/Lib/sgmllib.py +++ b/Lib/sgmllib.py @@ -29,7 +29,12 @@ starttagopen = re.compile('<[>a-zA-Z]') shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/') shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/') piclose = re.compile('>') -endbracket = re.compile('[<>]') +starttag = re.compile(r'<[a-zA-Z][-_.:a-zA-Z0-9]*\s*(' + r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*' + r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~@]' + r'[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*(?=[\s>/<])))?' + r')*\s*/?\s*(?=[<>])') +endtag = re.compile(r'])') tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*') attrfind = re.compile( r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*' @@ -245,11 +250,10 @@ class SGMLParser(markupbase.ParserBase): self.finish_shorttag(tag, data) self.__starttag_text = rawdata[start_pos:match.end(1) + 1] return k - # XXX The following should skip matching quotes (' or ") - match = endbracket.search(rawdata, i+1) + match = starttag.match(rawdata, i) if not match: return -1 - j = match.start(0) + j = match.end(0) # Now parse the data between i+1 and j into a tag and attrs attrs = [] if rawdata[i:i+2] == '<>': @@ -283,10 +287,10 @@ class SGMLParser(markupbase.ParserBase): # Internal -- parse endtag def parse_endtag(self, i): rawdata = self.rawdata - match = endbracket.search(rawdata, i+1) + match = endtag.match(rawdata, i) if not match: return -1 - j = match.start(0) + j = match.end(0) tag = rawdata[i+2:j].strip().lower() if rawdata[j] == '>': j = j+1 diff --git a/Lib/test/test_sgmllib.py b/Lib/test/test_sgmllib.py index 5edad9753a6c..bf34124cc0be 100644 --- a/Lib/test/test_sgmllib.py +++ b/Lib/test/test_sgmllib.py @@ -214,6 +214,21 @@ DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN' ("starttag", "e", [("a", "rgb(1,2,3)")]), ]) + def test_attr_values_quoted_markup(self): + """Multi-line and markup in attribute values""" + self.check_events("""text""", + [("starttag", "a", [("title", "foo\n
bar")]), + ("data", "text"), + ("endtag", "a")]) + self.check_events("""text""", + [("starttag", "a", [("title", "less < than")]), + ("data", "text"), + ("endtag", "a")]) + self.check_events("""text""", + [("starttag", "a", [("title", "greater > than")]), + ("data", "text"), + ("endtag", "a")]) + def test_attr_funky_names(self): self.check_events("""""", [ ("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")]), -- 2.47.3