Bug for subsetted CFF font output
Hi, another bug in LuaTeX: If LuaTeX tries to calculate the size of a CFF table where the second entry in the table is a real number, `pack_real` is called with `work_buffer+i` for a small `i`. This causes aliasing issues because `work_buffer` writes into `work_buffer` using `sprintf`. So the output from `pack_real` modifies `work_buffer` before the digits are read completely, causing LuaTeX to complain about a "invalid character". An example to reproduce the issue: Run the following plainTeX document with the attached version of `LOGO10.otf` (the font was created by reordering the Private table entries and has an invalid checksum, but this is ignored by LuaTeX) \directlua{ font.current(font.define{ name='logo', embedding='subset', encodingbytes=2, format='opentype', filename='LOGO10.otf', characters={ [0x41] = { width = 1000, height = 1000, depth = 1000, index = 0x2, } }, }) } A \bye This can be fixed by adding a separate temporary buffer for `pack_real`: diff --git a/source/texk/web2c/luatexdir/font/writecff.c b/source/texk/web2c/luatexdir/font/writecff.c index cf0751179..1217d1a52 100644 --- a/source/texk/web2c/luatexdir/font/writecff.c +++ b/source/texk/web2c/luatexdir/font/writecff.c @@ -1171,6 +1171,7 @@ static long pack_integer(card8 * dest, long destlen, long value) static long pack_real(card8 * dest, long destlen, double value) { + static char temp_buffer[22]; long e; int i = 0, pos = 2; int res; @@ -1199,20 +1200,18 @@ static long pack_real(card8 * dest, long destlen, double value) e--; } } - res = sprintf(work_buffer, "%1.14g", value); + res = sprintf(temp_buffer, "%1.14g", value); if (res<0) normal_error("cff","invalid conversion"); - if (res>CFF_REAL_MAX_LEN) - res=CFF_REAL_MAX_LEN; for (i = 0; i < res; i++) { unsigned char ch = 0; - if (work_buffer[i] == '\0') { + if (temp_buffer[i] == '\0') { /*tex In fact |res| should prevent this. */ break; - } else if (work_buffer[i] == '.') { + } else if (temp_buffer[i] == '.') { ch = 0x0a; - } else if (work_buffer[i] >= '0' && work_buffer[i] <= '9') { - ch = (unsigned char) (work_buffer[i] - '0'); + } else if (temp_buffer[i] >= '0' && temp_buffer[i] <= '9') { + ch = (unsigned char) (temp_buffer[i] - '0'); } else { normal_error("cff","invalid character"); } @@ -1247,15 +1246,15 @@ static long pack_real(card8 * dest, long destlen, double value) pos++; } if (e != 0) { - sprintf(work_buffer, "%ld", e); + sprintf(temp_buffer, "%ld", e); for (i = 0; i < CFF_REAL_MAX_LEN; i++) { unsigned char ch = 0; - if (work_buffer[i] == '\0') { + if (temp_buffer[i] == '\0') { break; - } else if (work_buffer[i] == '.') { + } else if (temp_buffer[i] == '.') { ch = 0x0a; - } else if (work_buffer[i] >= '0' && work_buffer[i] <= '9') { - ch = (unsigned char) (work_buffer[i] - '0'); + } else if (temp_buffer[i] >= '0' && temp_buffer[i] <= '9') { + ch = (unsigned char) (temp_buffer[i] - '0'); } else { normal_error("cff","invalid character"); }
On Tue, Oct 23, 2018 at 10:53 AM Marcel Krüger
Hi,
another bug in LuaTeX: If LuaTeX tries to calculate the size of a CFF table where the second entry in the table is a real number, `pack_real` is called with `work_buffer+i` for a small `i`. This causes aliasing issues because `work_buffer` writes into `work_buffer` using `sprintf`. So the output from `pack_real` modifies `work_buffer` before the digits are read completely, causing LuaTeX to complain about a "invalid character".
An example to reproduce the issue:
Run the following plainTeX document with the attached version of `LOGO10.otf` (the font was created by reordering the Private table entries and has an invalid checksum, but this is ignored by LuaTeX)
hm, not sure about invalid checksum... can you try to fix it with ttx ? (be careful, change the name of the new otf ie CFFFont name etc) -- luigi
---- On Tue, 23 Oct 2018 11:21:33 +0200 luigi scarso
On Tue, Oct 23, 2018 at 10:53 AM Marcel Krüger
wrote: Hi, another bug in LuaTeX: If LuaTeX tries to calculate the size of a CFF table where the second entry in the table is a real number, `pack_real` is called with `work_buffer+i` for a small `i`. This causes aliasing issues because `work_buffer` writes into `work_buffer` using `sprintf`. So the output from `pack_real` modifies `work_buffer` before the digits are read completely, causing LuaTeX to complain about a "invalid character".
An example to reproduce the issue:
Run the following plainTeX document with the attached version of `LOGO10.otf` (the font was created by reordering the Private table entries and has an invalid checksum, but this is ignored by LuaTeX) hm, not sure about invalid checksum... can you try to fix it with ttx ? (be careful, change the name of the new otf ie CFFFont name etc) --luigi
I already tried, but tty always stores the BlueValues first. I originally triggered this when I had a font which had fractional BlueValues which are replaced by whole So fixing the checksum would need some other tool or manual calculation, but I do not think it is worth it: LuaTeX does not care (I regularly use auto-generated fonts with all checksums set to zero without problems) Also there are no checksums in the actual CFF part, only in the OTF wrapper which is mostly ignored anyway. Best regards Marcel
On Tue, Oct 23, 2018 at 11:58 AM Marcel Krüger
---- On Tue, 23 Oct 2018 11:21:33 +0200 luigi scarso < luigi.scarso@gmail.com> wrote ----
On Tue, Oct 23, 2018 at 10:53 AM Marcel Krüger
wrote: Hi, another bug in LuaTeX: If LuaTeX tries to calculate the size of a CFF
table where the second entry in the table is a real number,
`pack_real` is called with `work_buffer+i` for a small `i`. This causes aliasing issues because `work_buffer` writes into `work_buffer` using `sprintf`. So the output from `pack_real` modifies `work_buffer` before the digits are read completely, causing LuaTeX to complain about a "invalid character".
An example to reproduce the issue:
Run the following plainTeX document with the attached version of `LOGO10.otf` (the font was created by reordering the Private table entries and has an invalid checksum, but this is ignored by LuaTeX) hm, not sure about invalid checksum... can you try to fix it with ttx ? (be careful, change the name of the new otf ie CFFFont name etc) --luigi
I already tried, but tty always stores the BlueValues first. I originally triggered this when I had a font which had fractional BlueValues which are replaced by whole So fixing the checksum would need some other tool or manual calculation, but I do not think it is worth it: LuaTeX does not care (I regularly use auto-generated fonts with all checksums set to zero without problems) Also there are no checksums in the actual CFF part, only in the OTF wrapper which is mostly ignored anyway.
ok, I will check. My ttx looks ok \directlua{ font.current(font.define{ name='logo', embedding='subset', encodingbytes=2, format='opentype', filename='LOGO10a.otf', characters={ [0x41] = { width = 1000, height = 1000, depth = 1000, index = 0x2, } }, }) } A \bye -- luigi
participants (2)
-
luigi scarso
-
Marcel Krüger