The output of |urlencode is always HTML-safe

This commit is contained in:
René Kijewski
2024-07-09 09:01:36 +02:00
parent af02433c19
commit 4d1c62374a
3 changed files with 23 additions and 10 deletions

View File

@@ -17,7 +17,7 @@
E.g. maybe you would like to have "Rinja example application" as default title for
your pages, then simply add this text (without quotation marks) in the block!
The default content can be as complex as you need to to be.
The default content can be as complex as you need it to be.
E.g. it may contain any nodes like `{% if … %}`, and even other blocks.
~#}
<title>{% block title %}{% endblock %}</title>
@@ -55,13 +55,13 @@
{%- macro lang_select(handler, query) -%}
<ul id="lang-select">
{%- if lang != Lang::en -%}
<li><a href="{{ req.url_for(handler, [Lang::en])? }}{{ query|safe }}">This page in English</a></li>
<li><a href="{{ req.url_for(handler, [Lang::en])? }}{{ query }}">This page in English</a></li>
{%- endif -%}
{%- if lang != Lang::de -%}
<li><a href="{{ req.url_for(handler, [Lang::de])? }}{{ query|safe }}">Diese Seite auf deutsch.</a></li>
<li><a href="{{ req.url_for(handler, [Lang::de])? }}{{ query }}">Diese Seite auf deutsch.</a></li>
{%- endif -%}
{%- if lang != Lang::fr -%}
<li><a href="{{ req.url_for(handler, [Lang::fr])? }}{{ query|safe }}">Cette page est en français.</a></li>
<li><a href="{{ req.url_for(handler, [Lang::fr])? }}{{ query }}">Cette page est en français.</a></li>
{%- endif -%}
</ul>
{%- endmacro lang_select -%}

View File

@@ -386,6 +386,16 @@ const _: () = {
}
};
/// Like [`Safe`], but only for HTML output
pub struct HtmlSafeOutput<T: fmt::Display>(pub T);
impl<T: fmt::Display> fmt::Display for HtmlSafeOutput<T> {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
macro_rules! mark_html_safe {
($($ty:ty),* $(,)?) => {$(
impl HtmlSafe for $ty {}
@@ -411,6 +421,7 @@ impl<T: HtmlSafe + ?Sized> HtmlSafe for std::sync::Arc<T> {}
impl<T: HtmlSafe + ?Sized> HtmlSafe for std::sync::MutexGuard<'_, T> {}
impl<T: HtmlSafe + ?Sized> HtmlSafe for std::sync::RwLockReadGuard<'_, T> {}
impl<T: HtmlSafe + ?Sized> HtmlSafe for std::sync::RwLockWriteGuard<'_, T> {}
impl<T: HtmlSafe> HtmlSafe for HtmlSafeOutput<T> {}
impl<T: HtmlSafe> HtmlSafe for std::num::Wrapping<T> {}
impl<T> HtmlSafe for std::borrow::Cow<'_, T>

View File

@@ -12,8 +12,8 @@ use std::convert::Infallible;
use std::fmt::{self, Write};
pub use escape::{
e, escape, safe, AutoEscape, AutoEscaper, Escaper, Html, HtmlSafe, MaybeSafe, Safe, Text,
Unsafe,
e, escape, safe, AutoEscape, AutoEscaper, Escaper, Html, HtmlSafe, HtmlSafeOutput, MaybeSafe,
Safe, Text, Unsafe,
};
#[cfg(feature = "humansize")]
use humansize::{ISizeFormatter, ToF64, DECIMAL};
@@ -98,8 +98,8 @@ impl fmt::Display for FilesizeFormatFilter {
///
/// [`urlencode_strict`]: ./fn.urlencode_strict.html
#[inline]
pub fn urlencode<T: fmt::Display>(s: T) -> Result<impl fmt::Display, Infallible> {
Ok(UrlencodeFilter(s, URLENCODE_SET))
pub fn urlencode(s: impl fmt::Display) -> Result<HtmlSafeOutput<impl fmt::Display>, Infallible> {
Ok(HtmlSafeOutput(UrlencodeFilter(s, URLENCODE_SET)))
}
#[cfg(feature = "urlencode")]
@@ -118,8 +118,10 @@ pub fn urlencode<T: fmt::Display>(s: T) -> Result<impl fmt::Display, Infallible>
///
/// If you want to preserve `/`, see [`urlencode`](./fn.urlencode.html).
#[inline]
pub fn urlencode_strict<T: fmt::Display>(s: T) -> Result<impl fmt::Display, Infallible> {
Ok(UrlencodeFilter(s, URLENCODE_STRICT_SET))
pub fn urlencode_strict(
s: impl fmt::Display,
) -> Result<HtmlSafeOutput<impl fmt::Display>, Infallible> {
Ok(HtmlSafeOutput(UrlencodeFilter(s, URLENCODE_STRICT_SET)))
}
#[cfg(feature = "urlencode")]