rust-ammonia / ammonia

Repair and secure untrusted HTML
Apache License 2.0
523 stars 43 forks source link

Allow `UrlRelative::Custom` to hold value bound in some lifetime #175

Closed rhysd closed 1 year ago

rhysd commented 1 year ago

Problem

I have a some custom strategy on handling relative links. The following code is a minimized version of my original source code to explain the problem.

use ammonia::*;
use std::borrow::Cow;

struct Eval<'a>(&'a str);

impl<'a> UrlRelativeEvaluate for Eval<'a> {
    fn evaluate<'u>(&self, url: &'u str) -> Option<Cow<'u, str>> {
        let mut s = self.0.to_string();
        s.push_str(url);
        Some(Cow::Owned(s))
    }
}

fn main() {
    let prefix = "/prefix/".to_string();
    let eval = Eval(&prefix);

    let mut sanitizer = Builder::default();
    sanitizer.url_relative(UrlRelative::Custom(Box::new(eval)));
    let s = "<a href=\"foo\">link</a>".to_string();
    let s = sanitizer.clean(&s).to_string();
    println!("{}", s)
}

This code won't compile because UrlRelativeEvaluate requires 'static lifetime to its data. The compiler does not know that the lifetime of UrlRelativeEvaluate is equal or smaller than the lifetime of Builder.

error[E0597]: `prefix` does not live long enough
  --> src/main.rs:16:21
   |
16 |     let eval = Eval(&prefix);
   |                     ^^^^^^^ borrowed value does not live long enough
...
19 |     sanitizer.url_relative(UrlRelative::Custom(Box::new(eval)));
   |                                                -------------- cast requires that `prefix` is borrowed for `'static`
...
23 | }
   | - `prefix` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.
error: could not compile `ammonia` due to previous error

Requiring 'static is unnecessarily strict.