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; fd_set rfds;
struct timeval tv; 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. */ /* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(termstate->in_fd, &rfds); FD_SET(termstate->in_fd, &rfds);
/* Wait up to five seconds. */ /* Do not wait. */
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 0; tv.tv_usec = 0;

View File

@@ -117,6 +117,10 @@ struct termcurses_ops_s
/* Get a keycode value */ /* Get a keycode value */
CODE int (*getkeycode)(FAR struct termcurses_s *dev, int *specialkey, int *keymodifers); 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 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, int termcurses_getkeycode(FAR struct termcurses_s *term, FAR int *specialkey,
FAR int *keymodifiers); 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 #undef EXTERN
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -107,6 +107,7 @@ static int tcurses_vt100_setattributes(FAR struct termcurses_s *dev,
unsigned long attrib); unsigned long attrib);
static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev, static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev,
FAR int *specialkey, FAR int *keymodifers); FAR int *specialkey, FAR int *keymodifers);
static bool tcurses_vt100_checkkey(FAR struct termcurses_s *dev);
/************************************************************************************ /************************************************************************************
* Private Data * Private Data
@@ -120,7 +121,8 @@ static const struct termcurses_ops_s g_vt100_ops =
tcurses_vt100_getwinsize, tcurses_vt100_getwinsize,
tcurses_vt100_setcolors, tcurses_vt100_setcolors,
tcurses_vt100_setattributes, tcurses_vt100_setattributes,
tcurses_vt100_getkeycode tcurses_vt100_getkeycode,
tcurses_vt100_checkkey
}; };
/* VT100 terminal codes */ /* 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 */ /* 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) if (priv->keycount <= 0)
{ {
return -1; return -1;
@@ -1047,6 +1049,48 @@ static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev, FAR int *speci
return keycode; 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 * Public Functions
************************************************************************************/ ************************************************************************************/

View File

@@ -272,3 +272,25 @@ int termcurses_getkeycode(FAR struct termcurses_s *term, FAR int *specialkey,
return -1; 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;
}