Merge pull request #1742 from fonttools/name-handle-duplicate-name-records-different-string-types
[name] Handle duplicate name records with different `string` types
This commit is contained in:
commit
cea5abd676
@ -459,22 +459,32 @@ class NameRecord(object):
|
||||
if type(self) != type(other):
|
||||
return NotImplemented
|
||||
|
||||
# implemented so that list.sort() sorts according to the spec.
|
||||
selfTuple = (
|
||||
getattr(self, "platformID", None),
|
||||
getattr(self, "platEncID", None),
|
||||
getattr(self, "langID", None),
|
||||
getattr(self, "nameID", None),
|
||||
getattr(self, "string", None),
|
||||
)
|
||||
otherTuple = (
|
||||
getattr(other, "platformID", None),
|
||||
getattr(other, "platEncID", None),
|
||||
getattr(other, "langID", None),
|
||||
getattr(other, "nameID", None),
|
||||
getattr(other, "string", None),
|
||||
)
|
||||
return selfTuple < otherTuple
|
||||
try:
|
||||
# implemented so that list.sort() sorts according to the spec.
|
||||
selfTuple = (
|
||||
self.platformID,
|
||||
self.platEncID,
|
||||
self.langID,
|
||||
self.nameID,
|
||||
self.toBytes(),
|
||||
)
|
||||
otherTuple = (
|
||||
other.platformID,
|
||||
other.platEncID,
|
||||
other.langID,
|
||||
other.nameID,
|
||||
other.toBytes(),
|
||||
)
|
||||
return selfTuple < otherTuple
|
||||
except (UnicodeEncodeError, AttributeError):
|
||||
# This can only happen for
|
||||
# 1) an object that is not a NameRecord, or
|
||||
# 2) an unlikely incomplete NameRecord object which has not been
|
||||
# fully populated, or
|
||||
# 3) when all IDs are identical but the strings can't be encoded
|
||||
# for their platform encoding.
|
||||
# In all cases it is best to return NotImplemented.
|
||||
return NotImplemented
|
||||
|
||||
def __repr__(self):
|
||||
return "<NameRecord NameID=%d; PlatformID=%d; LanguageID=%d>" % (
|
||||
|
@ -53,6 +53,26 @@ class NameTableTest(unittest.TestCase):
|
||||
with self.assertRaises(TypeError):
|
||||
table.setName(1.000, 5, 1, 0, 0)
|
||||
|
||||
def test_names_sort_bytes_str(self):
|
||||
# Corner case: If a user appends a name record directly to `names`, the
|
||||
# `__lt__` method on NameRecord may run into duplicate name records where
|
||||
# one `string` is a str and the other one bytes, leading to an exception.
|
||||
table = table__n_a_m_e()
|
||||
table.names = [
|
||||
makeName("Test", 25, 3, 1, 0x409),
|
||||
makeName("Test".encode("utf-16be"), 25, 3, 1, 0x409),
|
||||
]
|
||||
table.compile(None)
|
||||
|
||||
def test_names_sort_bytes_str_encoding_error(self):
|
||||
table = table__n_a_m_e()
|
||||
table.names = [
|
||||
makeName("Test寬", 25, 1, 0, 0),
|
||||
makeName("Test鬆鬆", 25, 1, 0, 0),
|
||||
]
|
||||
with self.assertRaises(TypeError):
|
||||
table.names.sort()
|
||||
|
||||
def test_addName(self):
|
||||
table = table__n_a_m_e()
|
||||
nameIDs = []
|
||||
|
Loading…
x
Reference in New Issue
Block a user