1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 11:57:35 +00:00

LibPDF: Don't do special subr processing for type 2 CFFs

This is a subset of #21484: Type 2 CFFs never use the special subrs,
so stop doing them for type 2 at least for now.

Fixes an assert in 0000064.pdf in 0000.zip in the pdfa dataset
(a stack underflow because a subr is supposed to push a bunch of
stuff, but instead it ran one of the built-in routines instead of
the subr from the font file).

As discussed in #21484, this isn't right for type 1 CFFs either,
but just removing the code there regresses Tests/LibPDF/type1.pdf.
A slightly more involved thing is needed there; I added a FIXME
for that here.
This commit is contained in:
Nico Weber 2023-10-27 21:44:12 -04:00 committed by Tim Flynn
parent 5c0c55d2c0
commit e484fae8e1

View file

@ -397,6 +397,11 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
if (static_cast<size_t>(subr_number) >= subroutines.size()) if (static_cast<size_t>(subr_number) >= subroutines.size())
return error("Subroutine index out of range"); return error("Subroutine index out of range");
if (!is_type2) {
// FIXME: Hardcoding subrs 0-2 here is incorrect, since some fonts don't use the flex feature.
// For the ones that do, subrs 0-2 have fixed contents that have callothersubr instructions.
// The right thing to do is to implement callothersubr for subrs 0-3 and remove the hardcoding here.
// Subroutines 0-2 handle the flex feature. // Subroutines 0-2 handle the flex feature.
if (subr_number == 0) { if (subr_number == 0) {
if (state.flex_index != 14) if (state.flex_index != 14)
@ -415,19 +420,24 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
state.flex_feature = false; state.flex_feature = false;
state.sp = 0; state.sp = 0;
} else if (subr_number == 1) { break;
}
if (subr_number == 1) {
state.flex_feature = true; state.flex_feature = true;
state.flex_index = 0; state.flex_index = 0;
state.sp = 0; state.sp = 0;
} else if (subr_number == 2) { break;
}
if (subr_number == 2) {
state.sp = 0; state.sp = 0;
} else { break;
}
}
auto const& subr = subroutines[subr_number]; auto const& subr = subroutines[subr_number];
if (subr.is_empty()) if (subr.is_empty())
return error("Empty subroutine"); return error("Empty subroutine");
TRY(parse_glyph(subr, local_subroutines, global_subroutines, state, is_type2)); TRY(parse_glyph(subr, local_subroutines, global_subroutines, state, is_type2));
}
break; break;
} }