[post] Touch up and fixes

The get_glyph_from_name() is incorrect; needs fixing.
This commit is contained in:
Behdad Esfahbod 2017-10-25 17:40:50 -06:00
parent d9e166f74c
commit 543bd58d7a
2 changed files with 81 additions and 67 deletions

View File

@ -320,18 +320,15 @@ struct hb_ot_face_post_accelerator_t
} }
inline bool get_glyph_name (hb_codepoint_t glyph, inline bool get_glyph_name (hb_codepoint_t glyph,
char *name, unsigned int size) const char *name, unsigned int size) const
{ {
if (unlikely (!name) || unlikely(!size))
return false;
return this->post->get_glyph_name (glyph, name, size, this->post_len); return this->post->get_glyph_name (glyph, name, size, this->post_len);
} }
inline bool get_glyph_from_name (const char *name, int len, inline bool get_glyph_from_name (const char *name, int len,
hb_codepoint_t *glyph) const hb_codepoint_t *glyph) const
{ {
if (unlikely (!name) || unlikely(!len)) if (unlikely (!len))
return false; return false;
return this->post->get_glyph_from_name (name, len, glyph, this->post_len); return this->post->get_glyph_from_name (name, len, glyph, this->post_len);

View File

@ -113,69 +113,80 @@ struct post
return_trace (false); return_trace (false);
if (version.to_int () == 0x00020000) if (version.to_int () == 0x00020000)
{ {
const postV2Tail &v2 = StructAfter<postV2Tail>(*this); const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
return_trace (v2.sanitize (c)); return_trace (v2.sanitize (c));
} }
return_trace (true); return_trace (true);
} }
inline bool get_glyph_name (hb_codepoint_t glyph, inline bool get_glyph_name (hb_codepoint_t glyph,
char *buffer, unsigned int buffer_length, char *buffer, unsigned int buffer_length,
unsigned int blob_len) const unsigned int blob_len) const
{ {
if (version.to_int () == 0x00010000) if (version.to_int () == 0x00010000)
{ {
if (glyph >= NUM_FORMAT1_NAMES) if (glyph >= NUM_FORMAT1_NAMES)
return false; return false;
strncpy(buffer, format1_names[glyph], buffer_length); if (!buffer_length)
buffer[buffer_length] = '\0'; return true;
strncpy (buffer, format1_names[glyph], buffer_length);
buffer[buffer_length - 1] = '\0';
return true; return true;
} }
if (version.to_int () == 0x00020000) if (version.to_int () == 0x00020000)
{ {
const postV2Tail &v2 = StructAfter<postV2Tail>(*this); const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
if (glyph >= v2.numberOfGlyphs) if (glyph >= v2.numberOfGlyphs)
return false; return false;
if (!buffer_length)
return true;
unsigned int index = v2.glyphNameIndex[glyph]; unsigned int index = v2.glyphNameIndex[glyph];
if (index >= NUM_FORMAT1_NAMES) if (index < NUM_FORMAT1_NAMES)
{ {
unsigned int offset = min_size + v2.min_size + 2 * v2.numberOfGlyphs; if (!buffer_length)
char* data = (char*) this + offset; return true;
for (unsigned int i = 0; data < (char*) this + blob_len; i++) strncpy (buffer, format1_names[index], buffer_length);
{ buffer[buffer_length - 1] = '\0';
unsigned int name_length = data[0]; return true;
data++;
if (i == index - NUM_FORMAT1_NAMES)
{
unsigned int remaining = (char*) this + blob_len - data;
name_length = MIN (name_length, buffer_length);
name_length = MIN (name_length, remaining);
memcpy (buffer, data, name_length);
buffer[name_length] = '\0';
return true;
}
data += name_length;
}
return false;
} }
else index -= NUM_FORMAT1_NAMES;
unsigned int offset = min_size + v2.min_size + 2 * v2.numberOfGlyphs;
unsigned char *data = (unsigned char *) this + offset;
unsigned char *end = (unsigned char *) this + blob_len;
for (unsigned int i = 0; data < end; i++)
{ {
strncpy(buffer, format1_names[index], buffer_length); unsigned int name_length = data[0];
buffer[buffer_length] = '\0'; data++;
return true; if (i == index)
{
if (unlikely (!name_length))
return false;
unsigned int remaining = end - data;
name_length = MIN (name_length, buffer_length - 1);
name_length = MIN (name_length, remaining);
memcpy (buffer, data, name_length);
buffer[name_length] = '\0';
return true;
}
data += name_length;
} }
return false;
} }
return false; return false;
} }
inline bool get_glyph_from_name (const char *name, int len, inline bool get_glyph_from_name (const char *name, int len,
hb_codepoint_t *glyph, hb_codepoint_t *glyph,
unsigned int blob_len) const unsigned int blob_len) const
{ {
if (len < 0) if (len < 0)
len = strlen (name); len = strlen (name);
@ -184,45 +195,51 @@ struct post
{ {
for (int i = 0; i < NUM_FORMAT1_NAMES; i++) for (int i = 0; i < NUM_FORMAT1_NAMES; i++)
{ {
if (strncmp (name, format1_names[i], len) == 0) if (strncmp (name, format1_names[i], len) == 0 && format1_names[len] == '\0')
{ {
*glyph = i; *glyph = i;
return true; return true;
} }
} }
return false; return false;
} }
if (version.to_int () == 0x00020000) if (version.to_int () == 0x00020000)
{ {
const postV2Tail &v2 = StructAfter<postV2Tail>(*this); const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
unsigned int offset = min_size + v2.min_size + 2 * v2.numberOfGlyphs; unsigned int offset = min_size + v2.min_size + 2 * v2.numberOfGlyphs;
char* data = (char*) this + offset; char* data = (char*) this + offset;
/* XXX The following code is wrong. */
return false;
for (hb_codepoint_t gid = 0; gid < v2.numberOfGlyphs; gid++) for (hb_codepoint_t gid = 0; gid < v2.numberOfGlyphs; gid++)
{ {
unsigned int index = v2.glyphNameIndex[gid]; unsigned int index = v2.glyphNameIndex[gid];
if (index >= NUM_FORMAT1_NAMES) if (index < NUM_FORMAT1_NAMES)
{ {
for (unsigned int i = 0; data < (char*) this + blob_len; i++) if (strncmp (name, format1_names[index], len) == 0 && format1_names[len] == '\0')
{ {
unsigned int name_length = data[0]; *glyph = gid;
unsigned int remaining = (char*) this + blob_len - data - 1; return true;
name_length = MIN (name_length, remaining); }
if (name_length == len && strncmp (name, data + 1, len) == 0) continue;
{ }
*glyph = gid; index -= NUM_FORMAT1_NAMES;
return true;
} for (unsigned int i = 0; data < (char*) this + blob_len; i++)
data += name_length + 1; {
} unsigned int name_length = data[0];
return false; unsigned int remaining = (char*) this + blob_len - data - 1;
} name_length = MIN (name_length, remaining);
else if (strncmp (name, format1_names[index], len) == 0) if (name_length == (unsigned int) len && strncmp (name, data + 1, len) == 0)
{ {
*glyph = gid; *glyph = gid;
return true; return true;
} }
data += name_length + 1;
}
return false;
} }
return false; return false;