apps/graphics/pdcurs34/nuttx and system/termcurses: This commit fixes two issues:

1. A memory corruption issue that occurs from a paste operation that would overflow the fixed buffer size for keyboard processing.

2. A stall in getch() processing when there are cached keycodes in the termcurses emulation (tcurses_vt100.c).
This commit is contained in:
Ken Pettit 2019-01-08 08:21:39 -06:00 committed by Gregory Nutt
parent 3cdb6ec4ba
commit e1237bfefd
4 changed files with 91 additions and 3 deletions

View File

@ -167,12 +167,20 @@ bool PDC_check_key(void)
fd_set rfds;
struct timeval tv;
/* Test the registered tcurs interface for cached characters */
ret = termcurses_checkkey(termstate->tcurs);
if (ret)
{
return true;
}
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(termstate->in_fd, &rfds);
/* Wait up to five seconds. */
/* Do not wait. */
tv.tv_sec = 0;
tv.tv_usec = 0;

View File

@ -117,6 +117,10 @@ struct termcurses_ops_s
/* Get a keycode value */
CODE int (*getkeycode)(FAR struct termcurses_s *dev, int *specialkey, int *keymodifers);
/* Check for cached keycode value */
CODE bool (*checkkey)(FAR struct termcurses_s *dev);
};
struct termcurses_dev_s
@ -229,6 +233,16 @@ int termcurses_getwinsize(FAR struct termcurses_s *term, FAR struct winsize *win
int termcurses_getkeycode(FAR struct termcurses_s *term, FAR int *specialkey,
FAR int *keymodifiers);
/************************************************************************************
* Name: termcurses_checkkey
*
* Description:
* Check if there is a key waiting to be processed.
*
************************************************************************************/
bool termcurses_checkkey(FAR struct termcurses_s *term);
#undef EXTERN
#ifdef __cplusplus
}

View File

@ -107,6 +107,7 @@ static int tcurses_vt100_setattributes(FAR struct termcurses_s *dev,
unsigned long attrib);
static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev,
FAR int *specialkey, FAR int *keymodifers);
static bool tcurses_vt100_checkkey(FAR struct termcurses_s *dev);
/************************************************************************************
* Private Data
@ -120,7 +121,8 @@ static const struct termcurses_ops_s g_vt100_ops =
tcurses_vt100_getwinsize,
tcurses_vt100_setcolors,
tcurses_vt100_setattributes,
tcurses_vt100_getkeycode
tcurses_vt100_getkeycode,
tcurses_vt100_checkkey
};
/* VT100 terminal codes */
@ -831,7 +833,7 @@ static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev, FAR int *speci
{
/* Get next bytes from input stream */
priv->keycount = read(fd, priv->keybuf, sizeof(priv->keybuf));
priv->keycount = read(fd, priv->keybuf, sizeof(priv->keybuf)-1);
if (priv->keycount <= 0)
{
return -1;
@ -1047,6 +1049,48 @@ static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev, FAR int *speci
return keycode;
}
/************************************************************************************
* Check if a key is cached for processing.
*
************************************************************************************/
static bool tcurses_vt100_checkkey(FAR struct termcurses_s *dev)
{
FAR struct tcurses_vt100_s *priv;
int ret;
int fd;
fd_set rfds;
struct timeval tv;
priv = (FAR struct tcurses_vt100_s *) dev;
fd = priv->in_fd;
/* Test for queued characters */
if (priv->keycount > 0)
{
return true;
}
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
/* Wait up to 1000us for next character after ESC */
tv.tv_sec = 0;
tv.tv_usec = 0;
ret = select(1, &rfds, NULL, NULL, &tv);
if (ret > 0)
{
return true;
}
return false;
}
/************************************************************************************
* Public Functions
************************************************************************************/

View File

@ -272,3 +272,25 @@ int termcurses_getkeycode(FAR struct termcurses_s *term, FAR int *specialkey,
return -1;
}
/************************************************************************************
* Name: termcurses_checkkey
*
* Description:
* Check if there is a key waiting to be processed.
*
************************************************************************************/
bool termcurses_checkkey(FAR struct termcurses_s *term)
{
FAR struct termcurses_dev_s *dev = (FAR struct termcurses_dev_s *) term;
/* Call the dev function */
if (dev->ops->checkkey)
{
return dev->ops->checkkey(term);
}
return 0;
}