Discussion:
[Dev-luatex] Bug for subsetted CFF font output
Marcel Krüger
2018-10-23 08:53:07 UTC
Permalink
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");
}
luigi scarso
2018-10-23 09:21:33 UTC
Permalink
Post by 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".
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
Marcel Krüger
2018-10-23 09:57:56 UTC
Permalink
Post by 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".
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
luigi scarso
2018-10-23 10:13:56 UTC
Permalink
---- On Tue, 23 Oct 2018 11:21:33 +0200 luigi scarso <
Post by 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,
Post by Marcel Krüger
`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`.
Post by Marcel Krüger
So the output from `pack_real` modifies `work_buffer` before the
digits are read completely,
Post by Marcel Krüger
causing LuaTeX to complain about a "invalid character".
Run the following plainTeX document with the attached version of
`LOGO10.otf` (the font was created by reordering
Post by Marcel Krüger
the Private table entries and has an invalid checksum, but this is
ignored by LuaTeX)
Post by Marcel Krüger
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)
Post by Marcel Krüger
--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
Loading...