Skip to content

Commit

Permalink
[cff] Reject negative vsindex
Browse files Browse the repository at this point in the history
The spec declares vsindex as signed number, but signed index is
meaningless (and we already treat vsindex unsigned almost everywhere).
Fix the only place we treat it as unsigned and reject negative value.
  • Loading branch information
khaledhosny committed Dec 31, 2021
1 parent ab8e95d commit 18f08c4
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 7 deletions.
9 changes: 5 additions & 4 deletions src/cff.cc
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ bool ParsePrivateDictData(
std::vector<Operand> operands;
bool cff2 = (out_cff->major == 2);
bool blend_seen = false;
uint32_t vsindex = 0;
int32_t vsindex = 0;

// Since a Private DICT for FDArray might not have a Local Subr (e.g. Hiragino
// Kaku Gothic Std W8), we create an empty Local Subr here to match the size
Expand All @@ -413,7 +413,7 @@ bool ParsePrivateDictData(
if (type == DICT_DATA_FDARRAY) {
out_cff->local_subrs_per_font.push_back(new ots::CFFIndex);
if (cff2) {
out_cff->vsindex_per_font.push_back(0);
out_cff->vsindex_per_font.push_back(vsindex);
}
}

Expand Down Expand Up @@ -531,7 +531,8 @@ bool ParsePrivateDictData(
return OTS_FAILURE();
}
vsindex = operands.back().first;
if (vsindex >= out_cff->region_index_count.size()) {
if (vsindex < 0 ||
vsindex >= (int32_t)out_cff->region_index_count.size()) {
return OTS_FAILURE();
}
out_cff->vsindex_per_font.back() = vsindex;
Expand All @@ -545,7 +546,7 @@ bool ParsePrivateDictData(
if (operands.size() < 1) {
return OTS_FAILURE();
}
if (vsindex >= out_cff->region_index_count.size()) {
if (vsindex >= (int32_t)out_cff->region_index_count.size()) {
return OTS_FAILURE();
}
uint16_t k = out_cff->region_index_count.at(vsindex);
Expand Down
7 changes: 4 additions & 3 deletions src/cff_charstring.cc
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,8 @@ bool ExecuteCharStringOperator(ots::OpenTypeCFF& cff,
if (cs_ctx.blend_seen || cs_ctx.vsindex_seen) {
return OTS_FAILURE();
}
if (argument_stack->top() >= (int32_t)cff.region_index_count.size()) {
if (argument_stack->top() < 0 ||
argument_stack->top() >= (int32_t)cff.region_index_count.size()) {
return OTS_FAILURE();
}
cs_ctx.vsindex_seen = true;
Expand Down Expand Up @@ -992,8 +993,8 @@ bool ValidateCFFCharStrings(
if (fd_index >= (int32_t)cff.vsindex_per_font.size()) {
// shouldn't get this far with a font in this condition, but just in case
return OTS_FAILURE(); // fd_index out-of-range
}
cs_ctx.vsindex = cff.vsindex_per_font.at(fd_index);
}
cs_ctx.vsindex = cff.vsindex_per_font.at(fd_index);
}

#ifdef DUMP_T2CHARSTRING
Expand Down
Binary file not shown.
1 change: 1 addition & 0 deletions tests/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ fuzzing_fonts = good_fonts + bad_fonts + [
'fonts/fuzzing/011facefb10ee4f813117eae60bb5940a280ae30.woff2',
'fonts/fuzzing/0509e80afb379d16560e9e47bdd7d888bebdebc6.ttf',
'fonts/fuzzing/051d92f8bc6ff724511b296c27623f824de256e9.ttf',
'fonts/fuzzing/05a7abc8e4c954ef105d056bd6249c6fda96d4a8.otf',
'fonts/fuzzing/07f054357ff8638bac3711b422a1e31180bba863.ttf',
'fonts/fuzzing/10531f9105aa03bf6e0f9754ec8af33ed457ad5c.otf',
'fonts/fuzzing/11340844a1190f140c78a0a964d49b5985253ea0.woff2',
Expand Down

0 comments on commit 18f08c4

Please sign in to comment.