Merge pull request 'memories: deny Snapchat-prefixed filenames from timestamp parsing' (#81) from feature/filename-date-snapchat-denylist into master

Reviewed-on: #81
This commit was merged in pull request #81.
This commit is contained in:
2026-05-07 16:20:06 +00:00

View File

@@ -206,6 +206,20 @@ pub fn extract_date_from_filename(filename: &str) -> Option<DateTime<FixedOffset
let timestamp_str = captures.get(1)?.as_str();
let len = timestamp_str.len();
// Known apps whose filenames carry sequential IDs that happen to
// overlap real epoch values (e.g. `Snapchat-1021849065.mp4` parses
// as 2002-05-19, but the file was actually saved in 2021). The
// digits alone are indistinguishable from a unix timestamp, so we
// dispatch on the source-app prefix instead.
const NON_TIMESTAMP_PREFIXES: &[&str] = &["snapchat-"];
let lower = filename.to_ascii_lowercase();
if NON_TIMESTAMP_PREFIXES
.iter()
.any(|p| lower.starts_with(p))
{
return None;
}
// Skip autogenerated filenames that start with "10000" (e.g., 1000004178.jpg)
// These are not timestamps but auto-generated file IDs
if timestamp_str.starts_with("10000") {
@@ -640,6 +654,22 @@ mod tests {
assert!(extract_date_from_filename("IMG_21323906751390.jpeg").is_none());
}
#[test]
fn test_extract_date_from_filename_snapchat_should_not_match() {
// Snapchat-prefixed filenames carry sequential app-assigned IDs
// that happen to fall inside plausible epoch ranges. The two
// reported cases:
// Snapchat-1021849065.mp4 → 10 digits → 2002-05-19
// Snapchat-1751031586660373917.jpg → 19 digits → 2002-09-09
// Real save dates are 2021 and 2016 respectively per
// FileModifyDate; the prefix denylist forces a fall-through to
// fs_time.
assert!(extract_date_from_filename("Snapchat-1021849065.mp4").is_none());
assert!(extract_date_from_filename("Snapchat-1751031586660373917.jpg").is_none());
// Case-insensitive match — lowercase variant should also reject.
assert!(extract_date_from_filename("snapchat-1021849065.mp4").is_none());
}
// The obsolete `test_memory_date_priority_*` tests covered the old
// request-time waterfall in `get_memory_date_with_priority`. Their
// replacement lives in `crate::date_resolver::tests` (resolver