Merge pull request #3007 from kontur/name-sort-encode-warning-only

Make NameRecord comparison not fail on encoding errors #3006
This commit is contained in:
Cosimo Lupo 2023-02-27 16:31:19 +00:00 committed by GitHub
commit d4c5eac780
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 12 deletions

View File

@ -610,32 +610,38 @@ class NameRecord(object):
return NotImplemented
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):
except 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.
# fully populated
return NotImplemented
try:
# Include the actual NameRecord string in the comparison tuples
selfTuple = selfTuple + (self.toBytes(),)
otherTuple = otherTuple + (other.toBytes(),)
except UnicodeEncodeError as e:
# toBytes caused an encoding error in either of the two, so content
# to sorting based on IDs only
log.error("NameRecord sorting failed to encode: %s" % e)
# Implemented so that list.sort() sorts according to the spec by using
# the order of the tuple items and their comparison
return selfTuple < otherTuple
def __repr__(self):
return "<NameRecord NameID=%d; PlatformID=%d; LanguageID=%d>" % (
self.nameID,

View File

@ -72,15 +72,34 @@ class NameTableTest(unittest.TestCase):
]
table.compile(None)
def test_names_sort_bytes_str_encoding_error(self):
def test_names_sort_attributes(self):
table = table__n_a_m_e()
# Create an actual invalid NameRecord object
broken = makeName("Test", 25, 3, 1, 0x409)
delattr(broken, "platformID")
table.names = [
makeName("Test寬", 25, 1, 0, 0),
makeName("Test鬆鬆", 25, 1, 0, 0),
makeName("Test", 25, 3, 1, 0x409),
broken,
]
# Sorting these two is impossible, expect an error to be raised
with self.assertRaises(TypeError):
table.names.sort()
def test_names_sort_encoding(self):
"""
Confirm that encoding errors in name table strings do not prevent at
least sorting by other IDs
"""
table = table__n_a_m_e()
table.names = [
makeName("Mac Unicode 寬 encodes ok", 25, 3, 0, 0x409),
makeName("Win Latin 寬 fails to encode", 25, 1, 0, 0),
]
table.names.sort()
# Encoding errors or not, sort based on other IDs nonetheless
self.assertEqual(table.names[0].platformID, 1)
self.assertEqual(table.names[1].platformID, 3)
def test_addName(self):
table = table__n_a_m_e()
nameIDs = []