mirror of
https://github.com/storytold/wordcraft.git
synced 2026-10-30 05:17:25 -06:00
#3692: font names are debug-quoted in log warnings
Finding 46: install_font logged the caller-supplied file name raw when the
font couldn't be stored, and the desktop log writes line breaks as they
come, so a name could forge extra log records. The name is now logged
with {:?} (escaped and quoted), and so are the font-derived family names in
the two glyph-outline warnings, which come from a document's own fonts.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5155d2c18c
commit
6c6326486f
@@ -194,13 +194,13 @@ impl FontFace {
|
||||
self.location(),
|
||||
HintingOptions { engine: Engine::Interpreter, target: Target::Mono },
|
||||
)
|
||||
.map_err(|e| log::warn!("Cannot initialize outline interpreter for {}: {e}", self.family))
|
||||
.map_err(|e| log::warn!("Cannot initialize outline interpreter for {:?}: {e}", self.family))
|
||||
.ok()
|
||||
});
|
||||
let settings =
|
||||
hinter.as_ref().map_or_else(|| DrawSettings::unhinted(Size::unscaled(), self.location()), |h| DrawSettings::hinted(h, false));
|
||||
if let Err(e) = g.draw(settings, &mut pen) {
|
||||
log::warn!("Cannot draw glyph {gid} in {}: {e}", self.family);
|
||||
log::warn!("Cannot draw glyph {gid} in {:?}: {e}", self.family);
|
||||
return BezPath::new();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,7 +366,8 @@ impl FontDb {
|
||||
None
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("couldn't store the font {name} in {}: {e}", dir.display());
|
||||
// Debug-quoted: a line break in the supplied name must not start a forged log record.
|
||||
log::warn!("couldn't store the font {name:?} in {}: {e}", dir.display());
|
||||
Some(format!("added for this session only: couldn't store it in {}: {e}", dir.display()))
|
||||
}
|
||||
},
|
||||
@@ -903,6 +904,44 @@ pub(crate) mod tests {
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
/// The messages logged while this test binary runs.
|
||||
fn logged() -> &'static std::sync::Mutex<Vec<String>> {
|
||||
static LOG: std::sync::OnceLock<std::sync::Mutex<Vec<String>>> = std::sync::OnceLock::new();
|
||||
struct Capture;
|
||||
impl log::Log for Capture {
|
||||
fn enabled(&self, _: &log::Metadata) -> bool {
|
||||
true
|
||||
}
|
||||
fn log(&self, r: &log::Record) {
|
||||
if let Some(l) = LOG.get() {
|
||||
l.lock().unwrap().push(r.args().to_string());
|
||||
}
|
||||
}
|
||||
fn flush(&self) {}
|
||||
}
|
||||
LOG.get_or_init(|| {
|
||||
let _ = log::set_logger(&Capture);
|
||||
log::set_max_level(log::LevelFilter::Warn);
|
||||
std::sync::Mutex::new(Vec::new())
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_supplied_name_is_logged_escaped() {
|
||||
// #3692: a line break in the name must not start a forged record in the log file.
|
||||
let log = logged();
|
||||
let not_a_folder = temp_dir("not-a-folder");
|
||||
std::fs::write(¬_a_folder, b"x").unwrap();
|
||||
let db = db();
|
||||
db.load_user_fonts(¬_a_folder);
|
||||
let r = db.install_font("a\nERROR forged record.ttf", &renamed("SourceSans3-Regular.ttf", FAMILY)).unwrap();
|
||||
assert!(r.warning.is_some(), "the font can't be stored");
|
||||
let lines = log.lock().unwrap();
|
||||
let line = lines.iter().find(|l| l.contains("forged record")).unwrap();
|
||||
assert!(!line.contains('\n'), "{line}");
|
||||
let _ = std::fs::remove_file(¬_a_folder);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stored_names_are_safe_and_unique() {
|
||||
let ttf = renamed("SourceSans3-Regular.ttf", FAMILY);
|
||||
|
||||
Reference in New Issue
Block a user