mirror of
https://github.com/TheFunny/TelegramTwitterMediaBot.git
synced 2026-10-03 00:52:10 +00:00
fix: drop unsafe upstream media entries
This commit is contained in:
@@ -112,7 +112,7 @@ async fn refetch(
|
|||||||
let items: Vec<MediaItemPayload> = fetched
|
let items: Vec<MediaItemPayload> = fetched
|
||||||
.media
|
.media
|
||||||
.iter()
|
.iter()
|
||||||
.map(|media| media_to_payload(media, fetched.sensitive))
|
.filter_map(|media| media_to_payload(media, fetched.sensitive))
|
||||||
.collect();
|
.collect();
|
||||||
// The re-fetch may produce a fresh local file (ugoira / bsky remux): hand it
|
// The re-fetch may produce a fresh local file (ugoira / bsky remux): hand it
|
||||||
// to the same keep-alive registry the first fetch uses.
|
// to the same keep-alive registry the first fetch uses.
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ pub(super) fn cached_snapshot(fetched: &x_media::site::Fetched) -> Option<Cached
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn media_to_payload(media: &Media, sensitive: bool) -> MediaItemPayload {
|
pub(super) fn media_to_payload(media: &Media, sensitive: bool) -> Option<MediaItemPayload> {
|
||||||
let url = media.url();
|
let url = media.url();
|
||||||
// Only adapter-produced temp files may be non-HTTP. A bare path from an
|
// Only adapter-produced temp files may be non-HTTP. A bare path from an
|
||||||
// upstream JSON field must never reach InputFile::file().
|
// upstream JSON field must never reach InputFile::file().
|
||||||
@@ -192,18 +192,14 @@ pub(super) fn media_to_payload(media: &Media, sensitive: bool) -> MediaItemPaylo
|
|||||||
.is_some_and(|name| name.starts_with(x_media::TEMP_FILE_PREFIX));
|
.is_some_and(|name| name.starts_with(x_media::TEMP_FILE_PREFIX));
|
||||||
if !url.starts_with("http://") && !url.starts_with("https://") && !is_local_temp {
|
if !url.starts_with("http://") && !url.starts_with("https://") && !is_local_temp {
|
||||||
log::warn!("dropping media with a non-URL upstream path");
|
log::warn!("dropping media with a non-URL upstream path");
|
||||||
return MediaItemPayload::Photo {
|
return None;
|
||||||
media: MediaRef::Source(String::new()),
|
|
||||||
has_spoiler: sensitive,
|
|
||||||
fallback_url: None,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
let media_ref = MediaRef::Source(url.to_string());
|
let media_ref = MediaRef::Source(url.to_string());
|
||||||
let fallback_url = media
|
let fallback_url = media
|
||||||
.smaller_url()
|
.smaller_url()
|
||||||
.filter(|url| url.starts_with("http://") || url.starts_with("https://"))
|
.filter(|url| url.starts_with("http://") || url.starts_with("https://"))
|
||||||
.map(str::to_string);
|
.map(str::to_string);
|
||||||
match media {
|
Some(match media {
|
||||||
// A gif inside a group becomes a video item; a lone gif takes the
|
// A gif inside a group becomes a video item; a lone gif takes the
|
||||||
// animation path (see url_media).
|
// animation path (see url_media).
|
||||||
Media::Illustration { .. } => MediaItemPayload::Photo {
|
Media::Illustration { .. } => MediaItemPayload::Photo {
|
||||||
@@ -223,7 +219,7 @@ pub(super) fn media_to_payload(media: &Media, sensitive: bool) -> MediaItemPaylo
|
|||||||
thumbnail: thumbnail_for(media),
|
thumbnail: thumbnail_for(media),
|
||||||
fallback_url,
|
fallback_url,
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a task and handles the outcome: post-send actions on success, retry
|
/// Sends a task and handles the outcome: post-send actions on success, retry
|
||||||
@@ -662,11 +658,8 @@ async fn url_media_inner(
|
|||||||
let items: Vec<MediaItemPayload> = fetched
|
let items: Vec<MediaItemPayload> = fetched
|
||||||
.media
|
.media
|
||||||
.iter()
|
.iter()
|
||||||
.map(|media| media_to_payload(media, fetched.sensitive))
|
.filter_map(|media| media_to_payload(media, fetched.sensitive))
|
||||||
.collect();
|
.collect();
|
||||||
// The indicator switches to "sending photo/video" once the kinds
|
|
||||||
// are known; `items` is moved into the task below.
|
|
||||||
*hint.lock() = ActionHint::for_items(&items);
|
|
||||||
let task = build_send_task(
|
let task = build_send_task(
|
||||||
&chat_data,
|
&chat_data,
|
||||||
chat_id,
|
chat_id,
|
||||||
@@ -825,17 +818,7 @@ mod tests {
|
|||||||
thumbnail_url: Some("/etc/passwd".into()),
|
thumbnail_url: Some("/etc/passwd".into()),
|
||||||
fallback_url: Some("https://safe.example/fallback.jpg".into()),
|
fallback_url: Some("https://safe.example/fallback.jpg".into()),
|
||||||
};
|
};
|
||||||
match media_to_payload(&media, false) {
|
assert!(media_to_payload(&media, false).is_none());
|
||||||
MediaItemPayload::Photo {
|
|
||||||
media: MediaRef::Source(source),
|
|
||||||
fallback_url,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
assert!(source.is_empty());
|
|
||||||
assert_eq!(fallback_url.as_deref(), None);
|
|
||||||
}
|
|
||||||
other => panic!("expected rejected photo payload, got {other:?}"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The caption-quote threshold matches the post's text inside the caption,
|
/// The caption-quote threshold matches the post's text inside the caption,
|
||||||
|
|||||||
Reference in New Issue
Block a user