Skip to content

fix: escape special characters in task-list items on upload - #31

Merged
blaipr merged 1 commit into
mainfrom
fix/escape-task-and-panel-text
Sep 2, 2026
Merged

blaipr merged 1 commit into
mainfrom
fix/escape-task-and-panel-text

Conversation

@blaipr

@blaipr blaipr commented Sep 2, 2026

Copy link
Copy Markdown
Member

Problem

Step 6 of md_to_confluence_storage built each task body with "".join(str(c) for c in li.children). str() on a text node returns the raw text, so an item such as - [ ] check a < b or - [x] talk to R&D produced <span>check a < b</span> — invalid XML that Confluence rejects on upload and edit. Step 7 (panel bodies) used the same idiom; it happened to be safe because a blockquote's children are always <p> tags, but it was one refactor away from the same bug.

Change

Both steps now serialise with decode_contents(), which escapes text nodes the same way the rest of the document is escaped. A comment on the task-list step records why str() per child is wrong there.

Compatibility

Upload only. Pages whose checklists contain <, > or & now upload instead of failing; everything else serialises byte-for-byte as before (the round trip for such items is covered by a new test).

Checklist

  • ruff check src tests, ruff format --check src tests and python -m pytest tests/ pass
  • Tests added for the change (tests/test_task_lists.py, tests/test_md_to_storage.py)
  • Docs updated — not needed, no equivalence changed
  • docs/conversion.md — not needed
  • CHANGELOG.md updated under Unreleased

@blaipr
blaipr force-pushed the fix/escape-task-and-panel-text branch from 86b30fb to 7a69dd9 Compare September 2, 2026 22:35
@blaipr
blaipr merged commit 927154f into main Sep 2, 2026
1 check passed
@blaipr
blaipr deleted the fix/escape-task-and-panel-text branch September 2, 2026 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant