Fix for crash with invalid dates on Windows (#1837)
https://forums.ankiweb.net/t/bug-report-crashing-when-opening-deck-browser/19768 Caused by a note mtime that was 1000x larger than it should have been. Check DB will now fix this case (but there are others it still does not cover, such as invalid card/note IDs). https://docs.rs/chrono/0.4.19/x86_64-pc-windows-msvc/src/chrono/sys/windows.rs.html#128
This commit is contained in:
parent
df1f7ff96c
commit
d946e5ddd5
@ -206,7 +206,8 @@ impl Collection {
|
||||
let nids_by_notetype = self.storage.all_note_ids_by_notetype()?;
|
||||
let norm = self.get_config_bool(BoolKey::NormalizeNoteText);
|
||||
let usn = self.usn()?;
|
||||
let stamp = TimestampMillis::now();
|
||||
let stamp_millis = TimestampMillis::now();
|
||||
let stamp_secs = TimestampSecs::now();
|
||||
|
||||
let expanded_tags = self.storage.expanded_tags()?;
|
||||
self.storage.clear_all_tags()?;
|
||||
@ -221,7 +222,7 @@ impl Collection {
|
||||
None => {
|
||||
let first_note = self.storage.get_note(group.peek().unwrap().1)?.unwrap();
|
||||
out.notetypes_recovered += 1;
|
||||
self.recover_notetype(stamp, first_note.fields().len(), ntid)?
|
||||
self.recover_notetype(stamp_millis, first_note.fields().len(), ntid)?
|
||||
}
|
||||
Some(nt) => nt,
|
||||
};
|
||||
@ -252,6 +253,10 @@ impl Collection {
|
||||
out.field_count_mismatch += 1;
|
||||
}
|
||||
|
||||
if note.mtime > stamp_secs {
|
||||
note.mtime = stamp_secs;
|
||||
}
|
||||
|
||||
// note type ID may have changed if we created a recovery notetype
|
||||
note.notetype_id = nt.id;
|
||||
|
||||
|
@ -90,7 +90,7 @@ impl Collection {
|
||||
.and_then(|v| FixedOffset::west_opt(v * 60))
|
||||
.unwrap_or_else(|| FixedOffset::west(0));
|
||||
|
||||
let local_tz = TimestampSecs::now().local_utc_offset();
|
||||
let local_tz = TimestampSecs::now().local_utc_offset()?;
|
||||
|
||||
Ok(if self.server {
|
||||
config_tz
|
||||
|
@ -5,7 +5,7 @@ use std::time;
|
||||
|
||||
use chrono::prelude::*;
|
||||
|
||||
use crate::define_newtype;
|
||||
use crate::{define_newtype, prelude::*};
|
||||
|
||||
define_newtype!(TimestampSecs, i64);
|
||||
define_newtype!(TimestampMillis, i64);
|
||||
@ -31,18 +31,33 @@ impl TimestampSecs {
|
||||
TimestampMillis(self.0 * 1000)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub(crate) fn local_datetime(self) -> Result<DateTime<Local>> {
|
||||
std::panic::catch_unwind(|| Local.timestamp(self.0, 0))
|
||||
.map_err(|_err| AnkiError::invalid_input("invalid date"))
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub(crate) fn local_datetime(self) -> Result<DateTime<Local>> {
|
||||
Ok(Local.timestamp(self.0, 0))
|
||||
}
|
||||
|
||||
/// YYYY-mm-dd
|
||||
pub(crate) fn date_string(self) -> String {
|
||||
Local.timestamp(self.0, 0).format("%Y-%m-%d").to_string()
|
||||
self.local_datetime()
|
||||
.map(|dt| dt.format("%Y-%m-%d").to_string())
|
||||
.unwrap_or_else(|_err| "invalid date".to_string())
|
||||
}
|
||||
|
||||
/// HH-MM
|
||||
pub(crate) fn time_string(self) -> String {
|
||||
Local.timestamp(self.0, 0).format("%H:%M").to_string()
|
||||
self.local_datetime()
|
||||
.map(|dt| dt.format("%H:%M").to_string())
|
||||
.unwrap_or_else(|_err| "invalid date".to_string())
|
||||
}
|
||||
|
||||
pub fn local_utc_offset(self) -> FixedOffset {
|
||||
*Local.timestamp(self.0, 0).offset()
|
||||
pub fn local_utc_offset(self) -> Result<FixedOffset> {
|
||||
Ok(*self.local_datetime()?.offset())
|
||||
}
|
||||
|
||||
pub fn datetime(self, utc_offset: FixedOffset) -> DateTime<FixedOffset> {
|
||||
|
Loading…
Reference in New Issue
Block a user