From 58d591c2679ff87439d3d54d7a106e4f9ad53a63 Mon Sep 17 00:00:00 2001 From: Andrei Vacariu Date: Sun, 6 Dec 2015 00:29:41 -0800 Subject: [PATCH 1/2] Leave quotes around attributes containing = It's invalid HTML otherwise. Reference: http://www.w3.org/TR/html-markup/syntax.html#attr-value-unquoted --- htmlmin/escape.py | 2 +- htmlmin/tests/test_escape.py | 3 +++ htmlmin/tests/tests.py | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/htmlmin/escape.py b/htmlmin/escape.py index bf1c0cf..a355d29 100644 --- a/htmlmin/escape.py +++ b/htmlmin/escape.py @@ -61,7 +61,7 @@ def escape_attr_value(val, double_quote=False): elif "'" in val: return (val, DOUBLE_QUOTE) - if not val or any((c.isspace() for c in val)): + if not val or any((c.isspace() for c in val)) or '=' in val: return (val, DOUBLE_QUOTE) return (val, NO_QUOTES) diff --git a/htmlmin/tests/test_escape.py b/htmlmin/tests/test_escape.py index de51e2c..d088181 100644 --- a/htmlmin/tests/test_escape.py +++ b/htmlmin/tests/test_escape.py @@ -61,6 +61,9 @@ def test_quote_space(self): self.assertDoubleQuote(" foobar ", " foobar ") self.assertDoubleQuote("", "") + def test_quote_equal(self): + self.assertDoubleQuote("width=device-width", "width=device-width") + def test_force_double_quote(self): result = escape.escape_attr_value("foobar", double_quote=True) self.assertEqual('foobar', result[0]) diff --git a/htmlmin/tests/tests.py b/htmlmin/tests/tests.py index ff5047c..70044ce 100644 --- a/htmlmin/tests/tests.py +++ b/htmlmin/tests/tests.py @@ -313,14 +313,14 @@ def test_basic_minification_quality(self): with codecs.open('htmlmin/tests/large_test.html', encoding='utf-8') as inpf: inp = inpf.read() out = self.minify(inp) - self.assertEqual(len(inp) - len(out), 9579) + self.assertEqual(len(inp) - len(out), 9383) def test_high_minification_quality(self): import codecs with codecs.open('htmlmin/tests/large_test.html', encoding='utf-8') as inpf: inp = inpf.read() out = self.minify(inp, remove_all_empty_space=True, remove_comments=True) - self.assertEqual(len(inp) - len(out), 12693) + self.assertEqual(len(inp) - len(out), 12497) class TestMinifierObject(HTMLMinTestCase): __reference_texts__ = MINIFY_FUNCTION_TEXTS From 2463e28708851c6df09bdc1904061d471d24cff3 Mon Sep 17 00:00:00 2001 From: Andrei Vacariu Date: Wed, 16 Dec 2015 18:02:13 -0800 Subject: [PATCH 2/2] Ensure unquoted attr values don't contain ><=` Fixes mankyd/htmlmin#32 --- htmlmin/escape.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htmlmin/escape.py b/htmlmin/escape.py index a355d29..17e799b 100644 --- a/htmlmin/escape.py +++ b/htmlmin/escape.py @@ -30,6 +30,8 @@ except ImportError: from cgi import escape +import re + NO_QUOTES = 0 SINGLE_QUOTE = 1 DOUBLE_QUOTE = 2 @@ -61,7 +63,7 @@ def escape_attr_value(val, double_quote=False): elif "'" in val: return (val, DOUBLE_QUOTE) - if not val or any((c.isspace() for c in val)) or '=' in val: + if not val or any((c.isspace() for c in val)) or re.search(r"[=><`]", val): return (val, DOUBLE_QUOTE) return (val, NO_QUOTES)