bug-ncurses
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: TERM Name Gets Corrupted


From: Ilya Petrov
Subject: Re: TERM Name Gets Corrupted
Date: Fri, 29 Jun 2018 19:38:57 +0500

The problem happens in code like this:

char* tname = getenv("TERM");
printf("tname=%s\n", tname);
getenv("HOME"); // BOOM!
printf("tname=%s\n", tname);

The most expected output is:

tname=xterm-new
tname=xterm-new

However the standard is tricky:

The implementation of getenv() is not required to be reentrant.  The
string pointed to by the return value of getenv() may be statically
allocated, and can be modified by a subsequent call to getenv(),
putenv(3), setenv(3), or unsetenv(3). 

It means second `tname=` may be corrupted.
There are several issues about this on emscripten:

https://github.com/kripken/emscripten/issues/4226 (getenv: Calling getenv deallocate string previously returned)
https://github.com/kripken/emscripten/issues/5053 (getenv returns temporary strings?)

I don't think you should change your codebase, I just leave this information here for your consideration and possibly a comment.

On Fri, Jun 29, 2018 at 12:49 PM, Ilya Petrov <address@hidden> wrote:
Hello.

I supply TERM=xterm-new environment variable to ncurses, but somewhere in between this name gets corrupted to garbage like <�.
I instrumented some debug messages: BEFORE 1 - BEFORE 4 into ncurses-6.1/ncurses/tinfo/read_entry.c:

NCURSES_EXPORT(int)
_nc_read_entry2(const char *const name, char *const filename, TERMTYPE2 *const tp)
{
    int code = TGETENT_NO;
    TR(TRACE_DATABASE, (T_CALLED("BEFORE 1 name=%s)"), name));
    _nc_SPRINTF(filename, _nc_SLIMIT(PATH_MAX)
"%.*s", PATH_MAX - 1, name);
    TR(TRACE_DATABASE, (T_CALLED("BEFORE 2 name=%s)"), name));
    if (strlen(name) == 0
|| strcmp(name, ".") == 0
|| strcmp(name, "..") == 0
|| _nc_pathlast(name) != 0
|| strchr(name, NCURSES_PATHSEP) != 0) {
TR(TRACE_DATABASE, ("illegal or missing entry name '%s'", name));
    } else {
#if NCURSES_USE_DATABASE
DBDIRS state;
int offset;
const char *path;
  TR(TRACE_DATABASE, (T_CALLED("BEFORE 3 name=%s)"), name)); // LAST TIME LOOKS OK HERE
_nc_first_db(&state, &offset);
code = TGETENT_ERR;
while ((path = _nc_next_db(&state, &offset)) != 0) {
      TR(TRACE_DATABASE, (T_CALLED("BEFORE 4 name=%s)"), name)); // FIRST TIME CORRUPTED HERE
    code = _nc_read_tic_entry(filename, PATH_MAX, path, name, tp);
    if (code == TGETENT_YES) {
_nc_last_db();
break;
    }
}
#elif NCURSES_USE_TERMCAP
if (code != TGETENT_YES) {
    code = _nc_read_termcap_entry(name, tp);
    _nc_SPRINTF(filename, _nc_SLIMIT(PATH_MAX)
"%.*s", PATH_MAX - 1, _nc_get_source());
}
#endif
    }
    return code;
}

Here are the traces:

TRACING NCURSES version 6.1.20180127 (tracelevel=0x1fff)
called {initscr()
+ called {new_prescr()
_nc_alloc_screen_sp 0x802bd0
+ return }0x802bd0
+ called {newterm(0x802bd0, "xterm-new", 0x5f50,0x6054)
+ + called {setupterm("xterm-new",1,0xdddc)
your terminal name is xterm-new
+ + + called {BEFORE 1 name=xterm-new)
+ + + + called {BEFORE 2 name=xterm-new)
+ + + + + called {BEFORE 3 name=xterm-new)
+ + + + + + called {_nc_first_db
duplicate /usr/share/terminfo
not found /usr/share/terminfo
+ + + + + + return }
_nc_next_db 1 /home/web_user/.terminfo
+ + + + + + called {BEFORE 4 name=<�)
+ + + + + + + called {BEFORE 5 name=<�)
+ + + + + + + + called {_nc_read_tic_entry(file=0xdea0, path=/home/web_user/.terminfo, name=<�)
cannot open terminfo /home/web_user/.terminfo/</<� (errno=2)
+ + + + + + + + return }code 0
+ + + + + + + + called {del_curterm(0, 0x8033c0)
_nc_free_termtype((null))
+ + + + + + + + return }0
+ + + + + + + return }-1
+ + + + + + return }0

Could you, please, guide me if this bug is related to ncurses or to emscripten platfrom to which I compile.
My related StackOverflow question: https://stackoverflow.com/questions/51093924/how-to-debug-ncurses-app-compiled-with-emscripten

Thank you for your help,
Ilya.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]