From 6547724630c99c93d4634e79a2087a4639772515 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Tue, 2 Jan 2024 12:09:48 +0000 Subject: [PATCH] [colr] Make rejecting paint-graph cycles in COLRv1 a compile-time option. --- meson.build | 4 ++++ meson_options.txt | 1 + src/colr.cc | 13 +++++++++++++ 3 files changed, 18 insertions(+) diff --git a/meson.build b/meson.build index 56ce7ac6..a3b1e03c 100644 --- a/meson.build +++ b/meson.build @@ -24,6 +24,10 @@ if get_option('synthesize-gvar') conf.set('OTS_SYNTHESIZE_MISSING_GVAR', 1) endif +if get_option('colr-cycle-check') + conf.set('OTS_COLR_CYCLE_CHECK', 1) +endif + freetype = dependency('freetype2', required: false) if freetype.found() conf.set('HAVE_FREETYPE', 1) diff --git a/meson_options.txt b/meson_options.txt index 36968bee..01b4c923 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,3 +1,4 @@ +option('colr-cycle-check', type : 'boolean', value : true, description : 'Reject fonts with cycles in COLRv1 paint graph') option('graphite', type : 'boolean', value : true, description : 'Sanitize Graphite tables') option('synthesize-gvar', type : 'boolean', value : true, description : 'Synthesize an empty gvar if fvar is present') option('fuzzer_ldflags', type: 'string', description : 'Extra LDFLAGS used during linking of fuzzing binaries') diff --git a/src/colr.cc b/src/colr.cc index 8931c77c..a09d3ab3 100644 --- a/src/colr.cc +++ b/src/colr.cc @@ -193,7 +193,15 @@ bool ParsePaintColrLayers(const ots::Font* font, colrState& state) { if (setContains(state.visited, data)) { +#ifdef OTS_COLR_CYCLE_CHECK + // A cycle would imply an infinite loop during painting, unless the renderer + // detects and breaks it. To be safe, reject the table. return OTS_FAILURE_MSG("Cycle detected in PaintColrLayers"); +#else + // Just issue a warning and return (as we've already checked this subgraph). + OTS_WARNING("Cycle detected in COLRv1 glyph paint graph (PaintColrLayers)\n"); + return true; +#endif } state.visited.insert(data); @@ -393,7 +401,12 @@ bool ParsePaintColrGlyph(const ots::Font* font, colrState& state) { if (setContains(state.visited, data)) { +#ifdef OTS_COLR_CYCLE_CHECK return OTS_FAILURE_MSG("Cycle detected in PaintColrGlyph"); +#else + OTS_WARNING("Cycle detected in COLRv1 glyph paint graph (PaintColrGlyph)\n"); + return true; +#endif } state.visited.insert(data);