[cmap] Check GID before adding ranges in format 4 & 12
Fixes https://github.com/harfbuzz/harfbuzz/issues/2031
This commit is contained in:
parent
ce11df1b5b
commit
dd288840d6
|
@ -342,14 +342,22 @@ struct CmapSubtableFormat4
|
||||||
count--; /* Skip sentinel segment. */
|
count--; /* Skip sentinel segment. */
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
hb_codepoint_t start = this->startCount[i];
|
||||||
|
hb_codepoint_t end = this->endCount[i];
|
||||||
unsigned int rangeOffset = this->idRangeOffset[i];
|
unsigned int rangeOffset = this->idRangeOffset[i];
|
||||||
if (rangeOffset == 0)
|
if (rangeOffset == 0)
|
||||||
out->add_range (this->startCount[i], this->endCount[i]);
|
{
|
||||||
|
for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++)
|
||||||
|
{
|
||||||
|
hb_codepoint_t gid = (codepoint + this->idDelta[i]) & 0xFFFFu;
|
||||||
|
if (unlikely (!gid))
|
||||||
|
continue;
|
||||||
|
out->add (codepoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (hb_codepoint_t codepoint = this->startCount[i];
|
for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++)
|
||||||
codepoint <= this->endCount[i];
|
|
||||||
codepoint++)
|
|
||||||
{
|
{
|
||||||
unsigned int index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount;
|
unsigned int index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount;
|
||||||
if (unlikely (index >= this->glyphIdArrayLength))
|
if (unlikely (index >= this->glyphIdArrayLength))
|
||||||
|
@ -522,10 +530,18 @@ struct CmapSubtableLongSegmented
|
||||||
|
|
||||||
void collect_unicodes (hb_set_t *out) const
|
void collect_unicodes (hb_set_t *out) const
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < this->groups.len; i++) {
|
for (unsigned int i = 0; i < this->groups.len; i++)
|
||||||
out->add_range (this->groups[i].startCharCode,
|
{
|
||||||
hb_min ((hb_codepoint_t) this->groups[i].endCharCode,
|
hb_codepoint_t start = this->groups[i].startCharCode;
|
||||||
(hb_codepoint_t) HB_UNICODE_MAX));
|
hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups[i].endCharCode,
|
||||||
|
(hb_codepoint_t) HB_UNICODE_MAX);
|
||||||
|
for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++)
|
||||||
|
{
|
||||||
|
hb_codepoint_t gid = T::group_get_glyph (this->groups[i], codepoint);
|
||||||
|
if (unlikely (!gid))
|
||||||
|
continue;
|
||||||
|
out->add (codepoint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -49,6 +49,27 @@ test_collect_unicodes_format4 (void)
|
||||||
hb_face_destroy (face);
|
hb_face_destroy (face);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_collect_unicodes_format12_notdef (void)
|
||||||
|
{
|
||||||
|
hb_face_t *face = hb_test_open_font_file ("fonts/cmunrm.otf");
|
||||||
|
hb_set_t *codepoints = hb_set_create();
|
||||||
|
hb_codepoint_t cp;
|
||||||
|
|
||||||
|
hb_face_collect_unicodes (face, codepoints);
|
||||||
|
|
||||||
|
cp = HB_SET_VALUE_INVALID;
|
||||||
|
g_assert (hb_set_next (codepoints, &cp));
|
||||||
|
g_assert_cmpuint (0x20, ==, cp);
|
||||||
|
g_assert (hb_set_next (codepoints, &cp));
|
||||||
|
g_assert_cmpuint (0x21, ==, cp);
|
||||||
|
g_assert (hb_set_next (codepoints, &cp));
|
||||||
|
g_assert_cmpuint (0x22, ==, cp);
|
||||||
|
|
||||||
|
hb_set_destroy (codepoints);
|
||||||
|
hb_face_destroy (face);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_collect_unicodes_format12 (void)
|
test_collect_unicodes_format12 (void)
|
||||||
{
|
{
|
||||||
|
@ -101,6 +122,7 @@ main (int argc, char **argv)
|
||||||
hb_test_add (test_collect_unicodes);
|
hb_test_add (test_collect_unicodes);
|
||||||
hb_test_add (test_collect_unicodes_format4);
|
hb_test_add (test_collect_unicodes_format4);
|
||||||
hb_test_add (test_collect_unicodes_format12);
|
hb_test_add (test_collect_unicodes_format12);
|
||||||
|
hb_test_add (test_collect_unicodes_format12_notdef);
|
||||||
|
|
||||||
return hb_test_run();
|
return hb_test_run();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue