On Sun, 8 Mar 2026 at 20:30, Clemens Lode <[email protected]>
wrote:

> On Windows, io.open() returns nil, nil when opening a path returned by
> os.tmpname() for writing. The second return value should be an error
> string per the Lua 5.3 reference manual (ยง6.8), but it is nil. This
> appears to happen because openout_any = p (paranoid mode) blocks writes
> outside the current working directory. os.tmpname() returns an absolute
> path to the system temp directory, which is outside CWD. The blocking
> itself is reasonable, but the missing error string makes debugging
> difficult.
>
> LuaHBTeX version: tested both 1.22.0 (TeX Live 2025, Windows), and
> 1.24.0 (TeX Live 2026, Windows)
>
> MWE:
>
> \documentclass{article}
> \begin{document}
> \directlua{
>    local t = os.tmpname()
>    local f, e = io.open(t, "w")
>    texio.write_nl("tmpname: " .. t)
>    texio.write_nl("file:   " .. tostring(f))
>    texio.write_nl("error:  " .. tostring(e))
>    local f2, e2 = io.open("test-cwd.tmp", "w")
>    texio.write_nl("cwd file:  " .. tostring(f2))
>    if f2 then f2:close(); os.remove("test-cwd.tmp") end
> }
> \end{document}
>
> Output:
>
> tmpname: C:\Users\Clemens\AppData\Local\Temp\s1gyk.0
> file:   nil
> error:  nil
> cwd file: file (0000000007DDFAB0)
>
> Expected: The error line should contain a descriptive string (e.g.,
> "Permission denied") rather than nil.
>
> Root cause in luatex-core.lua (v1.161):
>
> The luatex_io_open override (lines 65-76) delegates to validoutput:
>
> local function validoutput(name,how)
>      return type(how) == "string" and find(how,"w") and
> kpse_outputnameok(name) and io_open(name,how)
> end
>
> When kpse_outputnameok(name) returns false, Lua's short-circuit "and"
> stops the chain and returns false -- the real io_open is never called,
> so no error string is ever produced. luatex_io_open then returns this
> bare falsy value with no second return value, violating the io.open
> contract (nil, errmsg, errno).
>
> The same issue exists in luatex_io_open_readonly (lines 78-84).
>
> Suggested fix:
>
> local function luatex_io_open(name,how)
>      local handle = validinput(name,how)
>      if handle then
>          kpse_recordinputfile(name,"r")
>      else
>          handle = validoutput(name,how)
>          if handle then
>              kpse_recordoutputfile(name,"w")
>          end
>      end
>      if not handle then
>          return nil, name .. ": kpse permission denied"
>      end
>      return handle
> end
>

hm
we have now LUATEXCOREVERSION = 1.180
I understand the issue, but you should rephrase it
on the latest version of luatex-core.lua.

--
luigi
_______________________________________________
dev-luatex mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to