mirror of
https://github.com/TheFunny/TelegramTwitterMediaBot.git
synced 2026-09-23 23:32:05 +00:00
caption: escape URLs/handles in HTML captions
Post URLs and author URLs were interpolated raw into <a href> attributes (and the raw user URL from empty_fetched into caption text), so crafted links could break the HTML parse and fail the send with a 400. All attribute interpolations now use encode_double_quoted_attribute; text stays encode_text.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
use super::model;
|
use super::model;
|
||||||
use crate::media::Media;
|
use crate::media::Media;
|
||||||
use crate::site::{FetchError, Fetched};
|
use crate::site::{FetchError, Fetched};
|
||||||
use html_escape::encode_text;
|
use html_escape::{encode_double_quoted_attribute, encode_text};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
@@ -224,8 +224,8 @@ impl Post {
|
|||||||
pub fn caption(&self) -> String {
|
pub fn caption(&self) -> String {
|
||||||
format!(
|
format!(
|
||||||
"{url}\n<a href=\"{author_url}\">{author}</a>: {text}",
|
"{url}\n<a href=\"{author_url}\">{author}</a>: {text}",
|
||||||
url = self.url(),
|
url = encode_double_quoted_attribute(&self.url()),
|
||||||
author_url = self.author_url(),
|
author_url = encode_double_quoted_attribute(&self.author_url()),
|
||||||
author = encode_text(&self.author),
|
author = encode_text(&self.author),
|
||||||
text = encode_text(&self.text),
|
text = encode_text(&self.text),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::model::{IllustrationModel, TypeModel};
|
use super::model::{IllustrationModel, TypeModel};
|
||||||
use crate::media::Media;
|
use crate::media::Media;
|
||||||
use crate::site::{FetchError, Fetched};
|
use crate::site::{FetchError, Fetched};
|
||||||
use html_escape::encode_text;
|
use html_escape::{encode_double_quoted_attribute, encode_text};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
@@ -48,9 +48,9 @@ impl Illustration {
|
|||||||
pub fn caption(&self) -> String {
|
pub fn caption(&self) -> String {
|
||||||
format!(
|
format!(
|
||||||
"<a href=\"{url}\">{title}</a> / <a href=\"{author_url}\">{author}</a>\n{tags}",
|
"<a href=\"{url}\">{title}</a> / <a href=\"{author_url}\">{author}</a>\n{tags}",
|
||||||
url = self.url(),
|
url = encode_double_quoted_attribute(&self.url()),
|
||||||
title = encode_text(&self.title),
|
title = encode_text(&self.title),
|
||||||
author_url = self.author_url(),
|
author_url = encode_double_quoted_attribute(&self.author_url()),
|
||||||
author = encode_text(&self.author),
|
author = encode_text(&self.author),
|
||||||
tags = encode_text(
|
tags = encode_text(
|
||||||
&self
|
&self
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::model;
|
use super::model;
|
||||||
use crate::media::Media;
|
use crate::media::Media;
|
||||||
use crate::site::{FetchError, Fetched};
|
use crate::site::{FetchError, Fetched};
|
||||||
use html_escape::encode_text;
|
use html_escape::{encode_double_quoted_attribute, encode_text};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
@@ -48,7 +48,9 @@ pub async fn fetch_from_url(url: &str) -> Result<Fetched, FetchError> {
|
|||||||
fn empty_fetched(url: &str) -> Fetched {
|
fn empty_fetched(url: &str) -> Fetched {
|
||||||
Fetched {
|
Fetched {
|
||||||
source_url: url.to_string(),
|
source_url: url.to_string(),
|
||||||
caption: url.to_string(),
|
// The raw user-supplied URL goes into an HTML caption; escape it so
|
||||||
|
// crafted links cannot break the parse (Telegram 400).
|
||||||
|
caption: encode_text(url).into_owned(),
|
||||||
title: String::new(),
|
title: String::new(),
|
||||||
media: vec![],
|
media: vec![],
|
||||||
sensitive: true,
|
sensitive: true,
|
||||||
@@ -151,8 +153,8 @@ impl Tweet {
|
|||||||
pub fn caption(&self) -> String {
|
pub fn caption(&self) -> String {
|
||||||
format!(
|
format!(
|
||||||
"{url}\n<a href=\"{author_url}\">{author}</a>: {text}",
|
"{url}\n<a href=\"{author_url}\">{author}</a>: {text}",
|
||||||
url = self.url(),
|
url = encode_double_quoted_attribute(&self.url()),
|
||||||
author_url = self.author_url(),
|
author_url = encode_double_quoted_attribute(&self.author_url()),
|
||||||
author = encode_text(&self.author),
|
author = encode_text(&self.author),
|
||||||
text = encode_text(&self.text),
|
text = encode_text(&self.text),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ async fn edit_message_handler(bot: &Bot, message: &Message) -> bool {
|
|||||||
};
|
};
|
||||||
let link = format!(
|
let link = format!(
|
||||||
"<a href=\"{0}\">{1}</a>",
|
"<a href=\"{0}\">{1}</a>",
|
||||||
edit.url,
|
html_escape::encode_double_quoted_attribute(&edit.url),
|
||||||
html_escape::encode_text(text)
|
html_escape::encode_text(text)
|
||||||
);
|
);
|
||||||
let new_text = if edit.template.is_empty() {
|
let new_text = if edit.template.is_empty() {
|
||||||
|
|||||||
Reference in New Issue
Block a user