Opened 3 weeks ago

Closed 2 weeks ago

Last modified 2 weeks ago

#37262 closed Bug (fixed)

Form media given as html-safe strings rendered as paths on 6.1

Reported by: Adam Johnson Owned by: Adam Johnson
Component: Forms Version: 6.1
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Adam Johnson)

Since #29490 (Django 4.1), Media assets may be given as hashable objects implementing __html__(), rendered verbatim as the complete tag, per the old "Paths as objects" docs section.
Html-safe strings from mark_safe() satisfy that contract, but since 8096b5251090bf7539c59956e398b027c7525529 (#37085) they are treated as static file paths instead: Media.__init__() now normalizes every isinstance(path, str) entry into Script/Stylesheet, and SafeString is a str subclass, so e.g. forms.Media(js=[mark_safe('<script defer src="https://example.org/asset.js"></script>')])
renders as<script src="/static/%3Cscript%20defer%20src%3D%22https%3A/..."></script> rather than the tag verbatim as in 6.0. The same happens for css entries but non-str @html_safe classes still work.

The fix is to skip normalization for any string that provides __html__(), so that they take the pre-existing verbatim rendering branch.

Change History (8)

comment:1 by Adam Johnson, 3 weeks ago

Description: modified (diff)

comment:2 by David Smith, 3 weeks ago

Triage Stage: UnreviewedAccepted

#37268 was also opened which seems to be a duplicate of this issue.

comment:3 by Adam Johnson, 3 weeks ago

That ticket looks subtly different to me, it seems the user was using translated paths for scripts or stylesheets and now they’re being eagerly translated rather than lazily wt request time.

comment:4 by blighj, 2 weeks ago

Patch needs improvement: set

comment:5 by Adam Johnson, 2 weeks ago

Patch needs improvement: unset

comment:6 by Jacob Walls, 2 weeks ago

Triage Stage: AcceptedReady for checkin

comment:7 by Jacob Walls <jacobtylerwalls@…>, 2 weeks ago

Resolution: fixed
Status: assignedclosed

In 99d56e5:

Fixed #37262 -- Restored rendering of html-safe strings in form media.

Media.__init__() normalized every string js/css entry into Script or
Stylesheet objects. SafeString is a str subclass, so html-safe strings
such as mark_safe("<script defer src=...></script>"), a previously-documented
idiom for including complete asset tags, were treated as asset paths,
run through static(), and percent-encoded instead of being rendered
verbatim.

Leave objects providing __html__() un-normalized so that they take the
verbatim rendering path, restoring the Django 6.0 behavior.

Regression in 8096b5251090bf7539c59956e398b027c7525529.

co-authored-by: Johannes Maron <johannes@…>

comment:8 by Jacob Walls <jacobtylerwalls@…>, 2 weeks ago

In 86093621:

[6.1.x] Fixed #37262 -- Restored rendering of html-safe strings in form media.

Media.__init__() normalized every string js/css entry into Script or
Stylesheet objects. SafeString is a str subclass, so html-safe strings
such as mark_safe("<script defer src=...></script>"), a previously-documented
idiom for including complete asset tags, were treated as asset paths,
run through static(), and percent-encoded instead of being rendered
verbatim.

Leave objects providing __html__() un-normalized so that they take the
verbatim rendering path, restoring the Django 6.0 behavior.

Regression in 8096b5251090bf7539c59956e398b027c7525529.

co-authored-by: Johannes Maron <johannes@…>

Backport of 99d56e5cf15839995f62f24294584f1e2976b1ea from main.

Note: See TracTickets for help on using tickets.
Back to Top