[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: lauxlib.c : luaL_loadfilex BUG : can loose OS error, fixed
- From: Massimo Sala <massimo.sala.71@...>
- Date: Mon, 11 May 2020 23:18:13 +0200
Current code of the function, last lines:
...
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
return errfile(L, "read", fnameindex);
}
lua_remove(L, fnameindex);
return status;
}
On some OS fclose could change errno. See for example
The fclose() function may also fail and set errno for any of the
errors specified for the routines close(2), write(2), or fflush(3).
A little improvement to preserve the OS error:
...
readstatus = ferror(lf.f);
if (readstatus)
readstatus_errno = errno;
if (filename)
fclose(lf.f); /* close file (could change errno) */
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
return errfile_custom(L, "read", strerror(readstatus_errno), fnameindex);
}
lua_remove(L, fnameindex);
return status;
}
See the attached file, I modified two functions and add a new one.
Best regards, Massimo
static int errfile_custom (lua_State *L, const char *what, const char *serr, int fnameindex) {
const char *filename = lua_tostring(L, fnameindex) + 1;
lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
lua_remove(L, fnameindex);
return LUA_ERRFILE;
}
static int errfile_errno (lua_State *L, const char *what, int fnameindex) {
return errfile_custom(L, what, strerror(errno), fnameindex);
}
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
const char *mode) {
LoadF lf;
int status, readstatus, readstatus_errno;
int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
if (filename == NULL) {
lua_pushliteral(L, "=stdin");
lf.f = stdin;
}
else {
lua_pushfstring(L, "@%s", filename);
lf.f = fopen(filename, "r");
if (lf.f == NULL) return errfile_errno(L, "open", fnameindex);
}
if (skipcomment(&lf, &c)) /* read initial portion */
lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
if (lf.f == NULL) return errfile_errno(L, "reopen", fnameindex);
skipcomment(&lf, &c); /* re-read initial portion */
}
if (c != EOF)
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
readstatus = ferror(lf.f);
if (readstatus)
readstatus_errno = errno;
if (filename)
fclose(lf.f); /* close file (could change errno) */
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
return errfile_custom(L, "read", strerror(readstatus_errno), fnameindex);
}
lua_remove(L, fnameindex);
return status;
}
_______________________________________________
lua-l mailing list -- lua-l@lists.lua.org
To unsubscribe send an email to lua-l-leave@lists.lua.org