Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

html_params does not work correctly for Markup values #801

Open
Daverball opened this issue Aug 9, 2023 · 1 comment
Open

html_params does not work correctly for Markup values #801

Daverball opened this issue Aug 9, 2023 · 1 comment

Comments

@Daverball
Copy link

Daverball commented Aug 9, 2023

While this is a bit of a corner case and could be considered bad form it can sometimes be the most simple solution when you want the rendering of dynamic elements to happen in the backend without having to involve AJAX. You can pass Markup into a HTML attribute just fine, since markupsafe.escape will just pass through Markup unchanged. However this will cause issues if the HTML contains any double quotes.

It's also worth noting that the same thing applies to any object that implements __html__.

Actual Behavior

>>> from markupsafe import Markup
>>> from wtforms.widgets import html_params
>>> html_params(data_render=Markup('<a href="#"></a>'))
'data-render="<a href="#"></a>"'

Expected Behavior

>>> from markupsafe import Markup
>>> from wtforms.widgets import html_params
>>> html_params(data_render=Markup('<a href="#"></a>'))
'data-render="<a href=&quot;#&quot;></a>"'

Environment

  • Python version: 3.10
  • wtforms version: 3.0.1

Suggested fix

Rather than doing the following in html_params

            params.append(f'{str(k)}="{escape(v)}"')

You would do the following

            v = escape(v).replace(Markup('"'), Markup('&quot;'))
            params.append(f'{str(k)}="{v}"')
@Daverball
Copy link
Author

It might also be a nice QoL improvement to wrap the return value in Markup, that way it would be possible to pass it into a Markup.format without having to wrap it manually.

So you could do this

Markup('<a {params}>{title}</a>').format(params=html_params(**params), title=title)

Instead of this (which could be marked as unsafe by a security linter)

Markup(f'<a {html_params(**params)}>{{title}}</a>').format(title=title)

Or this (which is more verbose)

Markup('<a {params}>{title}</a>').format(params=Markup(html_params(**params)), title=title)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant