Skip to content

Commit 3278ffc

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 3278ffc

7 files changed

Lines changed: 54 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: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,29 @@ 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(FPDF()._parse_chars("unrelated \\\\\\\\ quadruple escape \\**bold\\**", True))
136+
)
137+
expected = (Fragment("unrelated \\\\ quadruple escape **bold**", GSTATE, k=PDF.k),)
138+
assert frags == expected
139+
140+
frags = merge_fragments(
141+
tuple(FPDF()._parse_chars("unrelated \\\\\\\\\\ quintuple escape \\**bold\\**", True))
142+
)
143+
expected = (Fragment("unrelated \\\\\\ quintuple escape **bold**", GSTATE, k=PDF.k),)
125144
assert frags == expected
126145

127146

@@ -130,16 +149,42 @@ def test_markdown_parse_multiple_escape():
130149
tuple(FPDF()._parse_chars("\\\\**bold\\\\** double escaped", True))
131150
)
132151
expected = (
133-
Fragment("\\\\", GSTATE, k=PDF.k),
134-
Fragment("bold\\\\", GSTATE_B, k=PDF.k),
152+
Fragment("\\", GSTATE, k=PDF.k),
153+
Fragment("bold\\", GSTATE_B, k=PDF.k),
135154
Fragment(" double escaped", GSTATE, k=PDF.k),
136155
)
137-
138156
assert frags == expected
157+
139158
frags = merge_fragments(
140159
tuple(FPDF()._parse_chars("\\\\\\**triple bold\\\\\\** escaped", True))
141160
)
142-
expected = (Fragment("\\\\**triple bold\\\\** escaped", GSTATE, k=PDF.k),)
161+
expected = (Fragment("\\**triple bold\\** escaped", GSTATE, k=PDF.k),)
162+
assert frags == expected
163+
164+
frags = merge_fragments(
165+
tuple(FPDF()._parse_chars("\\\\\\\\**quadruple bold\\\\\\\\** escaped", True))
166+
)
167+
expected = (
168+
Fragment("\\\\", GSTATE, k=PDF.k),
169+
Fragment("quadruple bold\\\\", GSTATE_B, k=PDF.k),
170+
Fragment(" escaped", GSTATE, k=PDF.k),
171+
)
172+
assert frags == expected
173+
174+
frags = merge_fragments(
175+
tuple(FPDF()._parse_chars("\\\\\\\\\\**quintuple bold\\\\\\\\\\** escaped", True))
176+
)
177+
expected = (Fragment("\\\\**quintuple bold\\\\** escaped", GSTATE, k=PDF.k),)
178+
assert frags == expected
179+
180+
frags = merge_fragments(
181+
tuple(FPDF()._parse_chars("\\\\\\\\\\\\**sextuple bold\\\\\\\\\\\\** escaped", True))
182+
)
183+
expected = (
184+
Fragment("\\\\\\", GSTATE, k=PDF.k),
185+
Fragment("sextuple bold\\\\\\", GSTATE_B, k=PDF.k),
186+
Fragment(" escaped", GSTATE, k=PDF.k),
187+
)
143188
assert frags == expected
144189

145190

@@ -270,7 +315,7 @@ def test_markdown_parse_escape_non_marker():
270315
def test_markdown_parse_escape_before_marker_odd_even():
271316
frags = tuple(FPDF()._parse_chars("\\\\**bold**", True))
272317
expected = (
273-
Fragment("\\\\", GSTATE, k=PDF.k),
318+
Fragment("\\", GSTATE, k=PDF.k),
274319
Fragment("bold", GSTATE_B, k=PDF.k),
275320
)
276321
assert frags == expected

0 commit comments

Comments
 (0)