Skip to content

Fix duplicate default layer with a custom layer filter - #427

Merged
cmyr merged 2 commits into
mainfrom
fix-duplicate-default-layer
Oct 7, 2026
Merged

cmyr merged 2 commits into
mainfrom
fix-duplicate-default-layer

Conversation

@cmyr

@cmyr cmyr commented Oct 6, 2026

Copy link
Copy Markdown
Member

another funny little bug I found in the course of some other work:

LayerContents::load decided whether to synthesize an empty default layer by checking LayerFilter::includes_default_layer(), which only knows about the all/load_default flags. A custom filter_layers closure that admitted the real default layer got the placeholder pushed anyway, so the layer set ended up with two entries pointing at glyphs/, and saving would nondeterministically clobber the real layer's contents.plist with the empty one's.

Push the placeholder only when no loaded layer already has the default glyphs directory, and still fall through to MissingDefaultLayer when all/load_default was requested but the UFO genuinely has no default layer.

LayerContents::load decided whether to synthesize an empty default
layer by checking LayerFilter::includes_default_layer(), which only
knows about the all/load_default flags. A custom filter_layers
closure that admitted the real default layer got the placeholder
pushed anyway, so the layer set ended up with two entries pointing at
glyphs/, and saving would nondeterministically clobber the real
layer's contents.plist with the empty one's.

Push the placeholder only when no loaded layer already has the
default glyphs directory, and still fall through to
MissingDefaultLayer when all/load_default was requested but the UFO
genuinely has no default layer.
Comment thread src/layer.rs Outdated
fn test_filter_admits_default_layer_no_duplicate() {
let ufo_path = "testdata/MutatorSansLightWide.ufo";
let request = DataRequest::none()
.filter_layers(|name, _path| name == "public.default" || name == "foreground");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the docstring says the filter admits the default layer "by name or by path", but the test only goes by name (and "public.default" doesn't match anything in this fixture, the default layer is called "foreground"). Maybe you can add a second request with |_, p| p == Path::new("glyphs"), since a path-only filter hits the same duplicate on main

A path-only filter hit the same duplicate layer bug. Also drop the
public.default check, which never matched in this UFO.
@cmyr
cmyr merged commit d5b94b5 into main Oct 7, 2026
5 checks passed
@cmyr
cmyr deleted the fix-duplicate-default-layer branch October 7, 2026 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants