Skip to content

Detecting the format symbols in description.#42

Open
tmikula-dev wants to merge 9 commits intomasterfrom
fix/27-detect-the-format-symbols-desc
Open

Detecting the format symbols in description.#42
tmikula-dev wants to merge 9 commits intomasterfrom
fix/27-detect-the-format-symbols-desc

Conversation

@tmikula-dev
Copy link
Copy Markdown
Collaborator

@tmikula-dev tmikula-dev commented Apr 22, 2026

Overview

This pull request introduces a new utility function to sanitize block-level Markdown, ensuring that text rendered in issue bodies does not accidentally trigger Markdown formatting. It applies this sanitization to security issue generation, particularly for fields that may contain user-supplied or external Markdown content. The changes also include comprehensive tests for the new helper.

Release Notes

  • Logic that detects a formatting symbols inside of the issue description

Related

Closes #27

Summary by CodeRabbit

Bug Fixes

  • Fixed an issue where markdown syntax characters in security issue content (such as remediation instructions, issue titles, and alert messages) were being unintentionally rendered as markdown formatting. User-provided text now displays correctly as plain content.

@tmikula-dev tmikula-dev self-assigned this Apr 22, 2026
@tmikula-dev tmikula-dev added the bug Something isn't working label Apr 22, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Walkthrough

The PR introduces markdown content sanitization to prevent formatting symbols from breaking GitHub issue templates. A new sanitize_markdown utility escapes block-level Markdown constructs (headings, blockquotes, horizontal rules, and table pipes) in user-provided issue content before template rendering.

Changes

Cohort / File(s) Summary
Documentation Updates
.github/copilot-instructions.md
Updated Python style guideline for __init__ methods to exclude test modules from documentation requirements.
Markdown Sanitization Utility
src/core/helpers.py
Introduced sanitize_markdown(text: str) -> str function with regex patterns to detect and escape block-level Markdown constructs (headings, blockquotes, pipes, horizontal rules) while preserving inline formatting.
Builder Integration
src/security/issues/builder.py
Applied sanitize_markdown to user-visible fields: remediation in alert_extra_data, parent and child issue titles from rule_description, and child issue body message content before template rendering.
Test Coverage
tests/core/test_helpers.py, tests/security/issues/test_builder.py
Added comprehensive tests for sanitize_markdown behavior across input categories (empty/plain text, block markers, inline formatting); refactored builder tests with parameterization to cover classification, title rendering, published dates, references, and markdown sanitization scenarios.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 A rabbit hops through issues bright,
Escaping symbols left and right!
No rogue ## shall break the frame,
Templates stay pristine—hooray for our claim! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.90% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Detecting the format symbols in description' accurately describes the main change: sanitizing Markdown format symbols in issue descriptions to prevent unintended formatting.
Description check ✅ Passed The PR description follows the template structure with Overview, Release Notes, and Related sections. It clearly explains the sanitization utility and its application to security issues.
Linked Issues check ✅ Passed The PR fully satisfies issue #27 requirements: it detects and eliminates formatting symbols (#, **, backticks, >, |, ---) from issue descriptions through the new sanitize_markdown utility and applies it to relevant fields.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #27: the new sanitize_markdown utility, its application to security issue fields, comprehensive tests, and minimal documentation updates. No extraneous changes detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/27-detect-the-format-symbols-desc

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@tmikula-dev tmikula-dev linked an issue Apr 22, 2026 that may be closed by this pull request
miroslavpojer
miroslavpojer previously approved these changes Apr 23, 2026
Base automatically changed from feature/remove-obsolete-parts to master April 24, 2026 13:46
@tmikula-dev tmikula-dev dismissed miroslavpojer’s stale review April 24, 2026 13:46

The base branch was changed.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/core/helpers.py (1)

64-67: Type hint doesn't reflect nullable input/return.

sanitize_markdown accepts and returns None (the early-return branch on falsy text), but the signature is declared as text: strstr. Static type checkers will flag the call sites that pass alert.metadata.rule_description or rule_id expressions where the left operand may legitimately be None, and callers forwarding the return value into template values. Please widen the annotation to reflect reality.

🔧 Proposed fix
-def sanitize_markdown(text: str) -> str:
-    """Escape block-level Markdown so text renders as plain content in an issue body."""
-    if not text:
-        return text
+def sanitize_markdown(text: str | None) -> str | None:
+    """Escape block-level Markdown so text renders as plain content in an issue body."""
+    if not text:
+        return text
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/helpers.py` around lines 64 - 67, The type annotations for
sanitize_markdown are incorrect because the function accepts and returns None;
update the signature to accept Optional[str] and return Optional[str] and add
the necessary typing import (Optional) so callers and static type checkers see
the nullable contract; keep the function behavior the same (early return when
text is falsy) and update any local references to the parameter type if needed.
tests/core/test_helpers.py (1)

30-31: Assert order: expected first.

-def test_passthrough_unchanged(text: str | None) -> None:
-    assert sanitize_markdown(text) == text
+def test_passthrough_unchanged(text: str | None) -> None:
+    assert text == sanitize_markdown(text)

As per coding guidelines: tests/**/*.py: Use assert pattern with expected first: assert expected == actual.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/core/test_helpers.py` around lines 30 - 31, The test assertion in
test_passthrough_unchanged uses actual first; change it to follow the
expected-first pattern by asserting the expected value (text) is equal to the
actual result of sanitize_markdown(text). Update the assertion in the
test_passthrough_unchanged function to use assert text ==
sanitize_markdown(text) so expected comes first and actual second.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/core/helpers.py`:
- Around line 23-30: The sanitizer in src/core/helpers.py currently escapes ATX
headings, blockquotes, HRs and table pipes but misses fenced code blocks and
setext H1 underlines; add regex patterns (e.g., _FENCE_RE =
re.compile(r"^(`{3,}|~{3,})", re.MULTILINE) and _SETEXT_RE =
re.compile(r"^(=+)\s*$", re.MULTILINE)) and apply them in the same sanitization
sequence where _HEADING_RE/_BLOCKQUOTE_RE/_HR_RE/_TABLE_RE are used (the
substitutions that write into the sanitized variable), and add a unit test case
exercising a fenced code block and an = underline so CHILD_BODY_TEMPLATE
headings aren’t swallowed.

In `@tests/security/issues/test_builder.py`:
- Line 326: The loop variable `l` in the generator expressions inside the
assertions (e.g., assert not any(l.strip().startswith("## Black") for l in
body.split("\n"))) is ambiguous and triggers ruff E741; rename it to a clearer
identifier such as `line` (or `ln`/`line_str`) in both occurrences (the one
shown and the similar one at the other assertion) so the expressions read like
any(line.strip().startswith(... ) for line in body.split("\n")) to resolve the
lint error.

---

Nitpick comments:
In `@src/core/helpers.py`:
- Around line 64-67: The type annotations for sanitize_markdown are incorrect
because the function accepts and returns None; update the signature to accept
Optional[str] and return Optional[str] and add the necessary typing import
(Optional) so callers and static type checkers see the nullable contract; keep
the function behavior the same (early return when text is falsy) and update any
local references to the parameter type if needed.

In `@tests/core/test_helpers.py`:
- Around line 30-31: The test assertion in test_passthrough_unchanged uses
actual first; change it to follow the expected-first pattern by asserting the
expected value (text) is equal to the actual result of sanitize_markdown(text).
Update the assertion in the test_passthrough_unchanged function to use assert
text == sanitize_markdown(text) so expected comes first and actual second.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8bb6d73f-3675-4964-bfd0-aab2e4d5a047

📥 Commits

Reviewing files that changed from the base of the PR and between c604531 and 4ea952d.

📒 Files selected for processing (5)
  • .github/copilot-instructions.md
  • src/core/helpers.py
  • src/security/issues/builder.py
  • tests/core/test_helpers.py
  • tests/security/issues/test_builder.py

Comment thread src/core/helpers.py
Comment thread tests/security/issues/test_builder.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Detect the format symbols in the issue description

2 participants