Commit b70d686 h
Changes: 3 files +16 -9
Changes (Side-by-Side)
share/jenny/lib/markdown.awk +1 -1
| |||
| 1 | Subproject commit 8cd72df31b3ae05a98735b419311da6274329401 |
||
| 1 | Subproject commit e518a9122b6d709032ecfd669f2446fdad7a36c9 |
||
test/regressions.sh +9 -3
md_render() { | |||
| 770 | printf '%s\n' "$1" | "$AWK" -f "$JENNY_SHARE_DIR/lib/markdown.awk/markdown.awk" |
770 | printf '%s\n' "$1" | "$AWK" -f "$JENNY_SHARE_DIR/lib/markdown.awk/markdown.awk" |
| 771 | } |
771 | } |
| 772 | |
772 | |
| 773 | # Raw HTML is escaped unless the caller asks for passthrough. The tests that |
||
| 774 | # examine how markdown interacts with real tags need the tags to survive. |
||
| 775 | md_unsafe() { |
||
| 776 | printf '%s\n' "$1" | "$AWK" -v UNSAFE_HTML=1 -f "$JENNY_SHARE_DIR/lib/markdown.awk/markdown.awk" |
||
| 777 | } |
||
| 778 | |
||
| 773 | it "a two-space child nests inside its parent" |
779 | it "a two-space child nests inside its parent" |
| 774 | out=$(md_render '- a |
780 | out=$(md_render '- a |
| 775 | - b |
781 | - b |
suite "underscores in inline HTML" | |||
| 845 | it "an underscore that is a tag's whole content is literal" |
851 | it "an underscore that is a tag's whole content is literal" |
| 846 | # <span class="us">_</span> writes a visible underscore. It opened an <em> |
852 | # <span class="us">_</span> writes a visible underscore. It opened an <em> |
| 847 | # that swallowed the markup after it. |
853 | # that swallowed the markup after it. |
| 848 | assert_contains "$(md_render 'x <span class="us">_</span> y')" '<span class="us">_</span>' |
||
| 854 | assert_contains "$(md_unsafe 'x <span class="us">_</span> y')" '<span class="us">_</span>' |
||
| 849 | |
855 | |
| 850 | it "two such underscores do not pair across their tags" |
856 | it "two such underscores do not pair across their tags" |
| 851 | # They emitted mis-nested "<b><em></b> ... <b></em></b>". |
857 | # They emitted mis-nested "<b><em></b> ... <b></em></b>". |
| 852 | pair=$(md_render 'A <b>_</b> and <b>_</b> here.') |
||
| 858 | pair=$(md_unsafe 'A <b>_</b> and <b>_</b> here.') |
||
| 853 | assert_contains "$pair" '<b>_</b> and <b>_</b>' |
859 | assert_contains "$pair" '<b>_</b> and <b>_</b>' |
| 854 | assert_not_contains "$pair" '<em>' |
860 | assert_not_contains "$pair" '<em>' |
| 855 | |
861 | |
it "bold still works" | |||
| 860 | assert_contains "$(md_render 'Real __bold__ here.')" '<strong>bold</strong>' |
866 | assert_contains "$(md_render 'Real __bold__ here.')" '<strong>bold</strong>' |
| 861 | |
867 | |
| 862 | it "emphasis spanning a tag still works" |
868 | it "emphasis spanning a tag still works" |
| 863 | assert_contains "$(md_render 'A _em <b>x</b> more_ end.')" '<em>em <b>x</b> more</em>' |
||
| 869 | assert_contains "$(md_unsafe 'A _em <b>x</b> more_ end.')" '<em>em <b>x</b> more</em>' |
||
| 864 | |
870 | |
| 865 | it "intraword underscores are still literal" |
871 | it "intraword underscores are still literal" |
| 866 | assert_contains "$(md_render 'Use node_modules and snake_case_name.')" 'node_modules and snake_case_name' |
872 | assert_contains "$(md_render 'Use node_modules and snake_case_name.')" 'node_modules and snake_case_name' |
test/units.sh +6 -5
After.')" "<p>After.</p>" | |||
| 651 | it "a pipe in prose is not a table" |
651 | it "a pipe in prose is not a table" |
| 652 | assert_not_contains "$(md 'a | b in ordinary prose')" "<table>" |
652 | assert_not_contains "$(md 'a | b in ordinary prose')" "<table>" |
| 653 | |
653 | |
| 654 | # Markdown deliberately allows inline HTML, in cells as in prose. |
||
| 655 | # multimarkdown 6.6.0 emits <th> <b>x</b> </th> for this, and jenny's own |
||
| 656 | # prose handling passes raw HTML through too, so a cell must not differ. |
||
| 657 | it "raw html in a cell passes through, as in prose" |
||
| 654 | # A cell must handle raw HTML exactly as prose does. That used to mean both |
||
| 655 | # passed it through; it now means both escape it unless the caller asks for |
||
| 656 | # passthrough with UNSAFE_HTML=1. What matters is that a cell is not a hole in |
||
| 657 | # whichever rule is in force. |
||
| 658 | it "raw html in a cell is escaped, as in prose" |
||
| 658 | assert_contains "$(md '| <b>x</b> | |
659 | assert_contains "$(md '| <b>x</b> | |
| 659 | |---| |
660 | |---| |
| 660 | | a |')" "<b>x</b>" |
||
| 661 | | a |')" "<b>x</b>" |
||
| 661 | |
662 | |
| 662 | it "a table inside a fence is literal" |
663 | it "a table inside a fence is literal" |
| 663 | assert_contains "$(md '``` |
664 | assert_contains "$(md '``` |
Raw
commit b70d686e1e58f5abc33df834b07d71a10aa1cd1c
Author: Pat Ambrosio <cp.ambrosio@gmail.com>
Date: Sat Sep 5 10:21:34 2026 +0800
Take the parser's escape-by-default contract
Raw HTML is escaped now unless the caller asks for passthrough, so the
four tests here that assert passthrough had to say which contract they
are testing.
The table-cell test keeps its point: a cell must handle raw HTML exactly
as prose does. That used to mean both passed it through and now means
both escape it, and what it guards is that a cell is not a hole in
whichever rule is in force.
The three inline-HTML tests examine how underscores interact with real
tags -- an underscore that is a tag's whole content, two that must not
pair across their tags, emphasis spanning one. That is only observable
while the tags survive, so they ask for passthrough explicitly.
jenny itself passes no flag, so pages are built with the safe reading.
Nothing on the site relied on passthrough: rebuilt, no escaped tags
appear anywhere in the output.
diff --git a/share/jenny/lib/markdown.awk b/share/jenny/lib/markdown.awk
index 8cd72df..e518a91 160000
--- a/share/jenny/lib/markdown.awk
+++ b/share/jenny/lib/markdown.awk
@@ -1 +1 @@
-Subproject commit 8cd72df31b3ae05a98735b419311da6274329401
+Subproject commit e518a9122b6d709032ecfd669f2446fdad7a36c9
diff --git a/test/regressions.sh b/test/regressions.sh
index 8db745f..e63a470 100755
--- a/test/regressions.sh
+++ b/test/regressions.sh
@@ -770,6 +770,12 @@ md_render() {
printf '%s\n' "$1" | "$AWK" -f "$JENNY_SHARE_DIR/lib/markdown.awk/markdown.awk"
}
+# Raw HTML is escaped unless the caller asks for passthrough. The tests that
+# examine how markdown interacts with real tags need the tags to survive.
+md_unsafe() {
+ printf '%s\n' "$1" | "$AWK" -v UNSAFE_HTML=1 -f "$JENNY_SHARE_DIR/lib/markdown.awk/markdown.awk"
+}
+
it "a two-space child nests inside its parent"
out=$(md_render '- a
- b
@@ -845,11 +851,11 @@ suite "underscores in inline HTML"
it "an underscore that is a tag's whole content is literal"
# <span class="us">_</span> writes a visible underscore. It opened an <em>
# that swallowed the markup after it.
-assert_contains "$(md_render 'x <span class="us">_</span> y')" '<span class="us">_</span>'
+assert_contains "$(md_unsafe 'x <span class="us">_</span> y')" '<span class="us">_</span>'
it "two such underscores do not pair across their tags"
# They emitted mis-nested "<b><em></b> ... <b></em></b>".
-pair=$(md_render 'A <b>_</b> and <b>_</b> here.')
+pair=$(md_unsafe 'A <b>_</b> and <b>_</b> here.')
assert_contains "$pair" '<b>_</b> and <b>_</b>'
assert_not_contains "$pair" '<em>'
@@ -860,7 +866,7 @@ it "bold still works"
assert_contains "$(md_render 'Real __bold__ here.')" '<strong>bold</strong>'
it "emphasis spanning a tag still works"
-assert_contains "$(md_render 'A _em <b>x</b> more_ end.')" '<em>em <b>x</b> more</em>'
+assert_contains "$(md_unsafe 'A _em <b>x</b> more_ end.')" '<em>em <b>x</b> more</em>'
it "intraword underscores are still literal"
assert_contains "$(md_render 'Use node_modules and snake_case_name.')" 'node_modules and snake_case_name'
diff --git a/test/units.sh b/test/units.sh
index d73a960..6111c95 100755
--- a/test/units.sh
+++ b/test/units.sh
@@ -651,13 +651,14 @@ After.')" "<p>After.</p>"
it "a pipe in prose is not a table"
assert_not_contains "$(md 'a | b in ordinary prose')" "<table>"
-# Markdown deliberately allows inline HTML, in cells as in prose.
-# multimarkdown 6.6.0 emits <th> <b>x</b> </th> for this, and jenny's own
-# prose handling passes raw HTML through too, so a cell must not differ.
-it "raw html in a cell passes through, as in prose"
+# A cell must handle raw HTML exactly as prose does. That used to mean both
+# passed it through; it now means both escape it unless the caller asks for
+# passthrough with UNSAFE_HTML=1. What matters is that a cell is not a hole in
+# whichever rule is in force.
+it "raw html in a cell is escaped, as in prose"
assert_contains "$(md '| <b>x</b> |
|---|
-| a |')" "<b>x</b>"
+| a |')" "<b>x</b>"
it "a table inside a fence is literal"
assert_contains "$(md '```