fix: validate parent_id in error path, rebuild Tailwind CSS
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / ci (pull_request) Successful in 1m29s
CI / pr-e2e (pull_request) Successful in 1m44s

- Defensively parse parent_id in _render_htmx_error: coerce to int,
  fallback to main form if non-numeric or parent not found
- Rebuild Tailwind CSS to include new utility classes from templates
- Add test for tampered parent_id falling back to main form

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Mark
2026-03-04 00:00:23 +00:00
parent c01fc14258
commit 0eddb9696a
3 changed files with 29 additions and 10 deletions

View File

@@ -150,6 +150,20 @@ def test_non_htmx_post_still_redirects(client, _article):
assert resp["Location"].endswith("?commented=1") assert resp["Location"].endswith("?commented=1")
@pytest.mark.django_db
def test_htmx_error_with_tampered_parent_id_falls_back_to_main_form(client, _article):
"""Tampered/non-numeric parent_id falls back to main form error response."""
cache.clear()
resp = client.post(
"/comments/post/",
{"article_id": _article.id, "parent_id": "not-a-number", "author_name": "T",
"author_email": "t@t.com", "body": " ", "honeypot": ""},
HTTP_HX_REQUEST="true",
)
assert resp.status_code == 200
assert b"comment-form-container" in resp.content
# ── Turnstile Integration ──────────────────────────────────────────────────── # ── Turnstile Integration ────────────────────────────────────────────────────

View File

@@ -121,9 +121,14 @@ def _comment_template_context(comment, article, request):
class CommentCreateView(View): class CommentCreateView(View):
def _render_htmx_error(self, request, article, form): def _render_htmx_error(self, request, article, form):
"""Return error form partial for HTMX — swaps the form container itself.""" """Return error form partial for HTMX — swaps the form container itself."""
parent_id = request.POST.get("parent_id") raw_parent_id = request.POST.get("parent_id")
if parent_id: if raw_parent_id:
parent = Comment.objects.filter(pk=parent_id, article=article).first() try:
parent_id = int(raw_parent_id)
except (ValueError, TypeError):
parent_id = None
parent = Comment.objects.filter(pk=parent_id, article=article).first() if parent_id else None
if parent:
ctx = { ctx = {
"comment": parent, "page": article, "comment": parent, "page": article,
"turnstile_site_key": _turnstile_site_key(), "turnstile_site_key": _turnstile_site_key(),

File diff suppressed because one or more lines are too long