Repository: html5lib/html5lib-python

Issue:
Sanitizer removes the <ol> "reversed" attribute
`reversed` is a boolean attribute on `<ol>` that can be used to make descending lists. The sanitizer seems to be stripping this (it's not included in `allowed_attributes`).

https://html.spec.whatwg.org/multipage/semantics.html#attr-ol-reversed

Discussion:
codecov-io: # [Codecov](https://codecov.io/gh/html5lib/html5lib-python/pull/396?src=pr&el=h1) Report
> Merging [#396](https://codecov.io/gh/html5lib/html5lib-python/pull/396?src=pr&el=desc) into [master](https://codecov.io/gh/html5lib/html5lib-python/commit/4f9235752cea29c5a31721440578b430823a1e69?src=pr&el=desc) will **decrease** coverage by `0.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/html5lib/html5lib-python/pull/396/graphs/tree.svg?width=650&token=jxme1XHT1Q&height=150&src=pr)](https://codecov.io/gh/html5lib/html5lib-python/pull/396?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #396      +/-   ##
==========================================
- Coverage   90.79%   90.77%   -0.02%     
==========================================
  Files          50       50              
  Lines        6952     6962      +10     
  Branches     1328     1328              
==========================================
+ Hits         6312     6320       +8     
- Misses        481      483       +2     
  Partials      159      159
```


| [Impacted Files](https://codecov.io/gh/html5lib/html5lib-python/pull/396?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [html5lib/filters/sanitizer.py](https://codecov.io/gh/html5lib/html5lib-python/pull/396/diff?src=pr&el=tree#diff-aHRtbDVsaWIvZmlsdGVycy9zYW5pdGl6ZXIucHk=) | `93.16% <ø> (ø)` | :arrow_up: |
| [html5lib/constants.py](https://codecov.io/gh/html5lib/html5lib-python/pull/396/diff?src=pr&el=tree#diff-aHRtbDVsaWIvY29uc3RhbnRzLnB5) | `100% <ø> (ø)` | :arrow_up: |
| [html5lib/tests/test\_sanitizer.py](https://codecov.io/gh/html5lib/html5lib-python/pull/396/diff?src=pr&el=tree#diff-aHRtbDVsaWIvdGVzdHMvdGVzdF9zYW5pdGl6ZXIucHk=) | `95.34% <100%> (+0.75%)` | :arrow_up: |
| [html5lib/\_trie/\_base.py](https://codecov.io/gh/html5lib/html5lib-python/pull/396/diff?src=pr&el=tree#diff-aHRtbDVsaWIvX3RyaWUvX2Jhc2UucHk=) | `56.52% <0%> (-5.02%)` | :arrow_down: |
| [html5lib/\_inputstream.py](https://codecov.io/gh/html5lib/html5lib-python/pull/396/diff?src=pr&el=tree#diff-aHRtbDVsaWIvX2lucHV0c3RyZWFtLnB5) | `91.62% <0%> (-0.3%)` | :arrow_down: |
| [html5lib/treebuilders/dom.py](https://codecov.io/gh/html5lib/html5lib-python/pull/396/diff?src=pr&el=tree#diff-aHRtbDVsaWIvdHJlZWJ1aWxkZXJzL2RvbS5weQ==) | `89.22% <0%> (-0.2%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/html5lib/html5lib-python/pull/396?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/html5lib/html5lib-python/pull/396?src=pr&el=footer). Last update [4f92357...4b34642](https://codecov.io/gh/html5lib/html5lib-python/pull/396?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index cf95ea0..47dcda3 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -11,10 +11,15 @@ Features:
 * Add support for the ``<wbr>`` element in the sanitizer, `which indicates
   a line break opportunity <https://html.spec.whatwg.org/#the-wbr-element>`_.
   This element is allowed by default. (#395) (Thank you, Tom Most!)
+* Add support for serializing the ``<ol reversed>`` boolean attribute. (Thank
+  you, Tom Most!) (#396)
+* The ``<ol reversed>`` and ``<ol start>`` attributes are now permitted by the
+  sanitizer. (#321) (Thank you, Tom Most!)
 
 Bug fixes:
 
-* The sanitizer now permits ``<summary>`` tags.
+* The sanitizer now permits ``<summary>`` tags. It used to allow ``<details>``
+  already. (#423)
 
 1.1
 ~~~
diff --git a/html5lib/constants.py b/html5lib/constants.py
index e83bfb5..2fa4146 100644
--- a/html5lib/constants.py
+++ b/html5lib/constants.py
@@ -617,6 +617,7 @@ booleanAttributes = {
     "button": frozenset(["disabled", "autofocus"]),
     "input": frozenset(["disabled", "readonly", "required", "autofocus", "checked", "ismap"]),
     "select": frozenset(["disabled", "readonly", "autofocus", "multiple"]),
+    "ol": frozenset(["reversed"]),
     "output": frozenset(["disabled", "readonly"]),
     "iframe": frozenset(["seamless"]),
 }
diff --git a/html5lib/filters/sanitizer.py b/html5lib/filters/sanitizer.py
index f7ac8d9..81c85d4 100644
--- a/html5lib/filters/sanitizer.py
+++ b/html5lib/filters/sanitizer.py
@@ -365,6 +365,7 @@ allowed_attributes = frozenset((
     (None, 'maxsize'),
     (None, 'minsize'),
     (None, 'other'),
+    (None, 'reversed'),
     (None, 'rowalign'),
     (None, 'rowalign'),
     (None, 'rowalign'),
@@ -375,6 +376,7 @@ allowed_attributes = frozenset((
     (None, 'scriptlevel'),
     (None, 'selection'),
     (None, 'separator'),
+    (None, 'start'),
     (None, 'stretchy'),
     (None, 'width'),
     (None, 'width'),


Test patch:
diff --git a/html5lib/tests/test_sanitizer.py b/html5lib/tests/test_sanitizer.py
index a6cbd79..499310b 100644
--- a/html5lib/tests/test_sanitizer.py
+++ b/html5lib/tests/test_sanitizer.py
@@ -154,3 +154,21 @@ def test_uppercase_color_codes_in_style():
     sanitized = sanitize_html("<p style=\"border: 1px solid #A2A2A2;\"></p>")
     expected = '<p style=\"border: 1px solid #A2A2A2;\"></p>'
     assert expected == sanitized
+
+
+def test_ol_start_allowed():
+    sanitized = sanitize_html("<ol start=2><li>.</ol>")
+    expected = '<ol start="2"><li>.</li></ol>'
+    assert expected == sanitized
+
+
+def test_ol_type_allowed():
+    sanitized = sanitize_html("<ol type=I><li>.</ol>")
+    expected = '<ol type="I"><li>.</li></ol>'
+    assert expected == sanitized
+
+
+def test_ol_reversed_allowed():
+    sanitized = sanitize_html("<ol reversed><li>.</ol>")
+    expected = '<ol reversed><li>.</li></ol>'
+    assert expected == sanitized