diff --git a/src/error.rs b/src/error.rs index 2d6216ec..22a5fc72 100644 --- a/src/error.rs +++ b/src/error.rs @@ -19,7 +19,6 @@ pub enum Error { MissingDefaultLayer, MissingLayer(String), DuplicateLayer(String), - MissingLayerContents, InvalidColor(InvalidColorString), DuplicateGlyph { layer: String, @@ -44,6 +43,8 @@ pub enum Error { ExpectedPositiveValue, #[cfg(feature = "kurbo")] ConvertContour(ErrorKind), + MissingFile(String), + MissingUfoDir(String), } /// An error representing a failure to validate UFO groups. @@ -160,9 +161,6 @@ impl std::fmt::Display for Error { Error::MissingDefaultLayer => write!(f, "Missing default ('glyphs') layer."), Error::DuplicateLayer(name) => write!(f, "Layer name '{}' already exists.", name), Error::MissingLayer(name) => write!(f, "Layer name '{}' does not exist.", name), - Error::MissingLayerContents => { - write!(f, "Missing required 'layercontents.plist' file.") - } Error::DuplicateGlyph { layer, glyph } => { write!(f, "Glyph named '{}' already exists in layer '{}'", glyph, layer) } @@ -194,6 +192,12 @@ impl std::fmt::Display for Error { Error::ExpectedPositiveValue => { write!(f, "PositiveIntegerOrFloat expects a positive value.") } + Error::MissingFile(path) => { + write!(f, "missing required {} file", path) + } + Error::MissingUfoDir(path) => { + write!(f, "{} directory was not found", path) + } #[cfg(feature = "kurbo")] Error::ConvertContour(cause) => write!(f, "Failed to convert contour: '{}'", cause), } diff --git a/src/font.rs b/src/font.rs index 6dbd357f..af0b0d0d 100644 --- a/src/font.rs +++ b/src/font.rs @@ -118,7 +118,14 @@ impl Font { } fn load_impl(path: &Path, request: DataRequest) -> Result { + if !path.exists() { + return Err(Error::MissingUfoDir(path.display().to_string())); + } + let meta_path = path.join(METAINFO_FILE); + if !meta_path.exists() { + return Err(Error::MissingFile(meta_path.display().to_string())); + } let mut meta: MetaInfo = plist::from_file(meta_path)?; let lib_path = path.join(LIB_FILE); @@ -393,7 +400,7 @@ fn load_layers( ) -> Result { let layercontents_path = ufo_path.join(LAYER_CONTENTS_FILE); if meta.format_version == FormatVersion::V3 && !layercontents_path.exists() { - return Err(Error::MissingLayerContents); + return Err(Error::MissingFile(layercontents_path.display().to_string())); } LayerSet::load(ufo_path, glyph_names) } @@ -438,6 +445,49 @@ mod tests { assert_eq!(font_obj.features.unwrap(), "# this is the feature from lightWide\n"); } + #[test] + fn loading_invalid_ufo_dir_path() { + let path = "totally/bogus/filepath/font.ufo"; + let font_load_res = Font::load(path); + assert!(matches!(font_load_res, Err(Error::MissingUfoDir(_)))); + } + + #[test] + fn loading_missing_metainfo_plist_path() { + // This UFO source does not have a metainfo.plist file + // This should raise an error + let path = "testdata/ufo/Tester-MissingMetaInfo.ufo"; + let font_load_res = Font::load(path); + assert!(matches!(font_load_res, Err(Error::MissingFile(_)))); + } + + #[test] + fn loading_missing_layercontents_plist_path() { + // This UFO source does not have a layercontents.plist file + // This should raise an error + let path = "testdata/ufo/Tester-MissingLayerContents.ufo"; + let font_load_res = Font::load(path); + assert!(matches!(font_load_res, Err(Error::MissingFile(_)))); + } + + #[test] + fn loading_missing_glyphs_contents_plist_path() { + // This UFO source does not have contents.plist in the default glyphs + // directory. This should raise an error + let path = "testdata/ufo/Tester-MissingGlyphsContents.ufo"; + let font_load_res = Font::load(path); + assert!(matches!(font_load_res, Err(Error::MissingFile(_)))); + } + + #[test] + fn loading_missing_glyphs_contents_plist_path_background_layer() { + // This UFO source has a contents.plist in the default glyphs directory + // but not in the glyphs.background directory. This should raise an error + let path = "testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo"; + let font_load_res = Font::load(path); + assert!(matches!(font_load_res, Err(Error::MissingFile(_)))); + } + #[test] fn data_request() { let path = "testdata/mutatorSans/MutatorSansLightWide.ufo"; diff --git a/src/layer.rs b/src/layer.rs index e3bb437c..5f1d744a 100644 --- a/src/layer.rs +++ b/src/layer.rs @@ -239,6 +239,9 @@ impl Layer { names: &NameList, ) -> Result { let contents_path = path.join(CONTENTS_FILE); + if !contents_path.exists() { + return Err(Error::MissingFile(contents_path.display().to_string())); + } // these keys are never used; a future optimization would be to skip the // names and deserialize to a vec; that would not be a one-liner, though. let contents: BTreeMap = plist::from_file(contents_path)?; diff --git a/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs.background/layerinfo.plist b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs.background/layerinfo.plist new file mode 100644 index 00000000..87752a44 --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs.background/layerinfo.plist @@ -0,0 +1,8 @@ + + + + + color + 0,0.8,0.2,0.7 + + diff --git a/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs/contents.plist b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs/contents.plist new file mode 100644 index 00000000..d35e3dae --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs/contents.plist @@ -0,0 +1,8 @@ + + + + + space + space.glif + + diff --git a/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs/layerinfo.plist b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs/layerinfo.plist new file mode 100644 index 00000000..3cf39b47 --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs/layerinfo.plist @@ -0,0 +1,8 @@ + + + + + color + 1,0.75,0,0.7 + + diff --git a/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs/space.glif b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs/space.glif new file mode 100644 index 00000000..7ddce5c0 --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/glyphs/space.glif @@ -0,0 +1,7 @@ + + + + + + + diff --git a/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/layercontents.plist b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/layercontents.plist new file mode 100644 index 00000000..e9a336b2 --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/layercontents.plist @@ -0,0 +1,14 @@ + + + + + + foreground + glyphs + + + background + glyphs.background + + + diff --git a/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/metainfo.plist b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/metainfo.plist new file mode 100644 index 00000000..7b8b34ac --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents-BackgroundLayer.ufo/metainfo.plist @@ -0,0 +1,10 @@ + + + + + creator + com.github.fonttools.ufoLib + formatVersion + 3 + + diff --git a/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs.background/contents.plist b/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs.background/contents.plist new file mode 100644 index 00000000..1e96c942 --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs.background/contents.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs.background/layerinfo.plist b/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs.background/layerinfo.plist new file mode 100644 index 00000000..87752a44 --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs.background/layerinfo.plist @@ -0,0 +1,8 @@ + + + + + color + 0,0.8,0.2,0.7 + + diff --git a/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs/layerinfo.plist b/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs/layerinfo.plist new file mode 100644 index 00000000..3cf39b47 --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs/layerinfo.plist @@ -0,0 +1,8 @@ + + + + + color + 1,0.75,0,0.7 + + diff --git a/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs/space.glif b/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs/space.glif new file mode 100644 index 00000000..7ddce5c0 --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents.ufo/glyphs/space.glif @@ -0,0 +1,7 @@ + + + + + + + diff --git a/testdata/ufo/Tester-MissingGlyphsContents.ufo/layercontents.plist b/testdata/ufo/Tester-MissingGlyphsContents.ufo/layercontents.plist new file mode 100644 index 00000000..e9a336b2 --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents.ufo/layercontents.plist @@ -0,0 +1,14 @@ + + + + + + foreground + glyphs + + + background + glyphs.background + + + diff --git a/testdata/ufo/Tester-MissingGlyphsContents.ufo/metainfo.plist b/testdata/ufo/Tester-MissingGlyphsContents.ufo/metainfo.plist new file mode 100644 index 00000000..7b8b34ac --- /dev/null +++ b/testdata/ufo/Tester-MissingGlyphsContents.ufo/metainfo.plist @@ -0,0 +1,10 @@ + + + + + creator + com.github.fonttools.ufoLib + formatVersion + 3 + + diff --git a/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs.background/contents.plist b/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs.background/contents.plist new file mode 100644 index 00000000..1e96c942 --- /dev/null +++ b/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs.background/contents.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs.background/layerinfo.plist b/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs.background/layerinfo.plist new file mode 100644 index 00000000..87752a44 --- /dev/null +++ b/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs.background/layerinfo.plist @@ -0,0 +1,8 @@ + + + + + color + 0,0.8,0.2,0.7 + + diff --git a/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs/contents.plist b/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs/contents.plist new file mode 100644 index 00000000..d35e3dae --- /dev/null +++ b/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs/contents.plist @@ -0,0 +1,8 @@ + + + + + space + space.glif + + diff --git a/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs/layerinfo.plist b/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs/layerinfo.plist new file mode 100644 index 00000000..3cf39b47 --- /dev/null +++ b/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs/layerinfo.plist @@ -0,0 +1,8 @@ + + + + + color + 1,0.75,0,0.7 + + diff --git a/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs/space.glif b/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs/space.glif new file mode 100644 index 00000000..7ddce5c0 --- /dev/null +++ b/testdata/ufo/Tester-MissingLayerContents.ufo/glyphs/space.glif @@ -0,0 +1,7 @@ + + + + + + + diff --git a/testdata/ufo/Tester-MissingLayerContents.ufo/metainfo.plist b/testdata/ufo/Tester-MissingLayerContents.ufo/metainfo.plist new file mode 100644 index 00000000..7b8b34ac --- /dev/null +++ b/testdata/ufo/Tester-MissingLayerContents.ufo/metainfo.plist @@ -0,0 +1,10 @@ + + + + + creator + com.github.fonttools.ufoLib + formatVersion + 3 + + diff --git a/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs.background/contents.plist b/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs.background/contents.plist new file mode 100644 index 00000000..1e96c942 --- /dev/null +++ b/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs.background/contents.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs.background/layerinfo.plist b/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs.background/layerinfo.plist new file mode 100644 index 00000000..87752a44 --- /dev/null +++ b/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs.background/layerinfo.plist @@ -0,0 +1,8 @@ + + + + + color + 0,0.8,0.2,0.7 + + diff --git a/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs/contents.plist b/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs/contents.plist new file mode 100644 index 00000000..d35e3dae --- /dev/null +++ b/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs/contents.plist @@ -0,0 +1,8 @@ + + + + + space + space.glif + + diff --git a/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs/layerinfo.plist b/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs/layerinfo.plist new file mode 100644 index 00000000..3cf39b47 --- /dev/null +++ b/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs/layerinfo.plist @@ -0,0 +1,8 @@ + + + + + color + 1,0.75,0,0.7 + + diff --git a/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs/space.glif b/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs/space.glif new file mode 100644 index 00000000..7ddce5c0 --- /dev/null +++ b/testdata/ufo/Tester-MissingMetaInfo.ufo/glyphs/space.glif @@ -0,0 +1,7 @@ + + + + + + + diff --git a/testdata/ufo/Tester-MissingMetaInfo.ufo/layercontents.plist b/testdata/ufo/Tester-MissingMetaInfo.ufo/layercontents.plist new file mode 100644 index 00000000..e9a336b2 --- /dev/null +++ b/testdata/ufo/Tester-MissingMetaInfo.ufo/layercontents.plist @@ -0,0 +1,14 @@ + + + + + + foreground + glyphs + + + background + glyphs.background + + +