Skip to content

Commit

Permalink
Fix several issues exposed by the fonts posted in #3238
Browse files Browse the repository at this point in the history
- fix when /Private follows /CharStrings instead of vv
- fix expected ND and PD values
- handle the case where lenIV is not 4 (writing)
- write /Subrs properly, not just the "standard 5"
  • Loading branch information
justvanrossum committed Aug 3, 2023
1 parent ca1af8c commit 2808d99
Showing 1 changed file with 20 additions and 10 deletions.
30 changes: 20 additions & 10 deletions Lib/fontTools/t1Lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,13 @@ def encode_eexec(self, eexec_dict):

# '-|', '|-', '|'
RD_key, ND_key, NP_key = None, None, None
lenIV = 4
subrs = std_subrs

for key, value in eexec_dict.items():
# Ensure we look at Private first, because we need RD_key, ND_key, NP_key and lenIV
sortedItems = sorted(eexec_dict.items(), key=lambda item: item[0] != "Private")

for key, value in sortedItems:
if key == "Private":
pr = eexec_dict["Private"]
# follow t1write.c:writePrivateDict
Expand All @@ -183,20 +188,25 @@ def encode_eexec(self, eexec_dict):
for subkey, subvalue in pr.items():
if not RD_key and subvalue == RD_value:
RD_key = subkey
elif not ND_key and subvalue == ND_value:
elif not ND_key and subvalue in ND_values:
ND_key = subkey
elif not NP_key and subvalue == PD_value:
elif not NP_key and subvalue in PD_values:
NP_key = subkey

if subkey == "lenIV":
lenIV = subvalue

Check warning on line 197 in Lib/fontTools/t1Lib/__init__.py

View check run for this annotation

Codecov / codecov/patch

Lib/fontTools/t1Lib/__init__.py#L197

Added line #L197 was not covered by tests

if subkey == "OtherSubrs":
# XXX: assert that no flex hint is used
lines.append(self._tobytes(hintothers))
elif subkey == "Subrs":
# XXX: standard Subrs only
lines.append(b"/Subrs 5 array")
for i, subr_bin in enumerate(std_subrs):
for subr_bin in subvalue:
subr_bin.compile()
subrs = [subr_bin.bytecode for subr_bin in subvalue]
lines.append(f"/Subrs {len(subrs)} array".encode("ascii"))
for i, subr_bin in enumerate(subrs):
encrypted_subr, R = eexec.encrypt(
bytesjoin([char_IV, subr_bin]), 4330
bytesjoin([char_IV[:lenIV], subr_bin]), 4330
)
lines.append(
bytesjoin(
Expand All @@ -222,7 +232,7 @@ def encode_eexec(self, eexec_dict):
for glyph_name, char_bin in eexec_dict["CharStrings"].items():
char_bin.compile()
encrypted_char, R = eexec.encrypt(
bytesjoin([char_IV, char_bin.bytecode]), 4330
bytesjoin([char_IV[:lenIV], char_bin.bytecode]), 4330
)
lines.append(
bytesjoin(
Expand Down Expand Up @@ -634,5 +644,5 @@ def stringToLong(s):
eexec_IV = b"cccc"
char_IV = b"\x0c\x0c\x0c\x0c"
RD_value = ("string", "currentfile", "exch", "readstring", "pop")
ND_value = ("def",)
PD_value = ("put",)
ND_values = [("def",), ("noaccess", "def")]
PD_values = [("put",), ("noaccess", "put")]

0 comments on commit 2808d99

Please sign in to comment.