Exit code: 0
Wall time: 0.3 seconds
Output:
LuaTeX 1.24.0 accepts a TFM whose char_info word for a nonexistent character
contains an out-of-range index. TeX, pdfTeX, and XeTeX reject the same file
with "Bad metric (TFM) file."
Reproduction
------------
$ cat > gap.pl <<'EOF'
(FAMILY GAPTEST)
(DESIGNSIZE R 10.0)
(CHARACTER C A (CHARWD R 0.5))
(CHARACTER C E (CHARWD R 0.25))
EOF
$ pltotf gap.pl gap.tfm
$ python3 -c "b=bytearray(open('gap.tfm','rb').read()); b[102]=252; \
open('gap-bad.tfm','wb').write(bytes(b))"
This gives bc=65, ec=69, ni=1, and sets italic_index to 63 on character 66.
That character has width_index zero, so it does not exist in the font.
$ cat > t.tex <<'EOF'
\catcode`\{=1 \catcode`\}=2
\font\f=gap-bad \relax
\end
EOF
$ for e in tex pdftex luatex xetex; do
> printf "%-8s " $e
> $e --ini --interaction=nonstopmode t.tex 2>&1 | grep -q "not loadable" \
> && echo reject || echo ACCEPT
> done
tex reject
pdftex reject
luatex ACCEPT
xetex reject
The implementation difference
------------------------------
LuaTeX's "Read character data" loop contains this test:
for (k = bc; k <= ec; k++) {
store_char_info(k);
if (ci._width_index == 0)
continue;
if (ci._width_index >= nw || ci._height_index >= nh ||
ci._depth_index >= nd || ci._italic_index >= ni)
tfm_abort;
TeX's corresponding loop checks every char_info word in bc..ec. The same
width_index gate also skips LuaTeX's lig_tag, ext_tag, and charlist checks.
For the out-of-range index in this example, the skipped fields belong to a
character that will never be looked up. The practical consequence is still
that a damaged font can load under lualatex and fail under pdflatex, with no
clear indication of why the engines disagree.
TFtoPL has the same gate in tftopl.web, so LuaTeX currently agrees with TFtoPL
and disagrees with TeX. I have reported that inconsistency to tex-k separately.
If TFtoPL is changed to match TeX, LuaTeX may want to follow that change; if
the decision goes the other way, tex.web is the outlier instead.
--
jdw64
doogwoo(a)gmail.com
https://www.makonea.com
Hi Luigi,
Currently, running "context" (with no further flags) on the LuaTeX
manual will use ConTeXt's default engine (LuaMetaTeX currently), but the
LuaTeX manual unsurprisingly requires LuaTeX. The attached patch
modifies the directive line to request the LuaTeX engine explicitly, so
that both "context" and "context --luatex" will compile the manual using
the correct engine.
This was originally reported by DacrydiumGracile in the TeX.SE chat:
https://chat.stackexchange.com/transcript/message/69125695#69125695
Thanks,
-- Max