Skip to content

Commit 86455e9

Browse files
committed
markdown escaping: Fix injection of escapes
c437630 ("Fix markdown character escaping bug (issue #1236)") fixed the escaping of multiple markdown markers, but it dropped dividing by two the number of escaped characters being injected: - txt_frag[: -((num_escape_chars + 1) // 2)] + for _ in range(escape_run - 1): This restores dividing by two the number of escapes, and restores the test results accordingly, making it the behavior closer to https://spec.commonmark.org/dingus/ Fixes: #1215
1 parent 6b9983f commit 86455e9

7 files changed

Lines changed: 70 additions & 8 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ This can also be enabled programmatically with `warnings.simplefilter('default',
2626
* dependency extras for camelot-py and endesive on pyproject.toml - _cf._ [issue #1792](https://github.com/py-pdf/fpdf2/issues/1792)
2727
* preserve link annotations during dry-run of pdf.multi_cell - _cf._ [issue #1807](https://github.com/py-pdf/fpdf2/issues/1807)
2828
* preserve two consecutive markdown links (without space inbetween) - _cf._ [issue #1814](https://github.com/py-pdf/fpdf2/issues/1814)
29+
* number of surviving escape characters - .cf. [issue #1215](https://github.com/py-pdf/fpdf2/issues/1215)
2930
### Changed
3031
* skip byte-for-byte compressed data comparison when zlib-ng is detected, regardless of OS
3132

fpdf/fpdf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4486,7 +4486,7 @@ def frag() -> Fragment:
44864486
self.MARKDOWN_UNDERLINE_MARKER,
44874487
)
44884488
if is_escape_target and escape_run % 2 == 1:
4489-
for _ in range(escape_run - 1):
4489+
for _ in range(escape_run // 2):
44904490
txt_frag.append(self.MARKDOWN_ESCAPE_CHARACTER)
44914491
if current_fallback_font:
44924492
if txt_frag:
@@ -4495,7 +4495,7 @@ def frag() -> Fragment:
44954495
escape_next_marker = 2
44964496
escape_run = 0
44974497
continue
4498-
for _ in range(escape_run):
4498+
for _ in range((escape_run + 1) // 2):
44994499
txt_frag.append(self.MARKDOWN_ESCAPE_CHARACTER)
45004500
escape_run = 0
45014501

-1 Bytes
Binary file not shown.
1 Byte
Binary file not shown.
-1 Bytes
Binary file not shown.
24 Bytes
Binary file not shown.

test/text/test_markdown_parse.py

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,39 @@ def test_markdown_unrelated_escape():
118118
)
119119
expected = (Fragment("unrelated \\ escape **bold**", GSTATE, k=PDF.k),)
120120
assert frags == expected
121+
121122
frags = merge_fragments(
122123
tuple(FPDF()._parse_chars("unrelated \\\\ double escape \\**bold\\**", True))
123124
)
124-
expected = (Fragment("unrelated \\\\ double escape **bold**", GSTATE, k=PDF.k),)
125+
expected = (Fragment("unrelated \\ double escape **bold**", GSTATE, k=PDF.k),)
126+
assert frags == expected
127+
128+
frags = merge_fragments(
129+
tuple(FPDF()._parse_chars("unrelated \\\\\\ triple escape \\**bold\\**", True))
130+
)
131+
expected = (Fragment("unrelated \\\\ triple escape **bold**", GSTATE, k=PDF.k),)
132+
assert frags == expected
133+
134+
frags = merge_fragments(
135+
tuple(
136+
FPDF()._parse_chars(
137+
"unrelated \\\\\\\\ quadruple escape \\**bold\\**", True
138+
)
139+
)
140+
)
141+
expected = (Fragment("unrelated \\\\ quadruple escape **bold**", GSTATE, k=PDF.k),)
142+
assert frags == expected
143+
144+
frags = merge_fragments(
145+
tuple(
146+
FPDF()._parse_chars(
147+
"unrelated \\\\\\\\\\ quintuple escape \\**bold\\**", True
148+
)
149+
)
150+
)
151+
expected = (
152+
Fragment("unrelated \\\\\\ quintuple escape **bold**", GSTATE, k=PDF.k),
153+
)
125154
assert frags == expected
126155

127156

@@ -130,16 +159,48 @@ def test_markdown_parse_multiple_escape():
130159
tuple(FPDF()._parse_chars("\\\\**bold\\\\** double escaped", True))
131160
)
132161
expected = (
133-
Fragment("\\\\", GSTATE, k=PDF.k),
134-
Fragment("bold\\\\", GSTATE_B, k=PDF.k),
162+
Fragment("\\", GSTATE, k=PDF.k),
163+
Fragment("bold\\", GSTATE_B, k=PDF.k),
135164
Fragment(" double escaped", GSTATE, k=PDF.k),
136165
)
137-
138166
assert frags == expected
167+
139168
frags = merge_fragments(
140169
tuple(FPDF()._parse_chars("\\\\\\**triple bold\\\\\\** escaped", True))
141170
)
142-
expected = (Fragment("\\\\**triple bold\\\\** escaped", GSTATE, k=PDF.k),)
171+
expected = (Fragment("\\**triple bold\\** escaped", GSTATE, k=PDF.k),)
172+
assert frags == expected
173+
174+
frags = merge_fragments(
175+
tuple(FPDF()._parse_chars("\\\\\\\\**quadruple bold\\\\\\\\** escaped", True))
176+
)
177+
expected = (
178+
Fragment("\\\\", GSTATE, k=PDF.k),
179+
Fragment("quadruple bold\\\\", GSTATE_B, k=PDF.k),
180+
Fragment(" escaped", GSTATE, k=PDF.k),
181+
)
182+
assert frags == expected
183+
184+
frags = merge_fragments(
185+
tuple(
186+
FPDF()._parse_chars("\\\\\\\\\\**quintuple bold\\\\\\\\\\** escaped", True)
187+
)
188+
)
189+
expected = (Fragment("\\\\**quintuple bold\\\\** escaped", GSTATE, k=PDF.k),)
190+
assert frags == expected
191+
192+
frags = merge_fragments(
193+
tuple(
194+
FPDF()._parse_chars(
195+
"\\\\\\\\\\\\**sextuple bold\\\\\\\\\\\\** escaped", True
196+
)
197+
)
198+
)
199+
expected = (
200+
Fragment("\\\\\\", GSTATE, k=PDF.k),
201+
Fragment("sextuple bold\\\\\\", GSTATE_B, k=PDF.k),
202+
Fragment(" escaped", GSTATE, k=PDF.k),
203+
)
143204
assert frags == expected
144205

145206

@@ -270,7 +331,7 @@ def test_markdown_parse_escape_non_marker():
270331
def test_markdown_parse_escape_before_marker_odd_even():
271332
frags = tuple(FPDF()._parse_chars("\\\\**bold**", True))
272333
expected = (
273-
Fragment("\\\\", GSTATE, k=PDF.k),
334+
Fragment("\\", GSTATE, k=PDF.k),
274335
Fragment("bold", GSTATE_B, k=PDF.k),
275336
)
276337
assert frags == expected

0 commit comments

Comments
 (0)