From: Rudolf Polzer <divver...@gmail.com> If more than `BUF_SIZE-2` bytes are read from the user, appending a newline and a zero byte overflows `userinputaux`, likely running into `userinputready` which _looks_ at least harmless, but is still undefined behavior. However, an assert exists to detect that and crash the engine:
``` $ perl -e 'syswrite STDOUT, "e4\n" x 5000' | src/gnuchess --uci GNU Chess gnuchess: engine.cc:520: void ForwardUserInputToEngine(): Assertion `nread+1 < BUF_SIZE-1' failed. zsh: done perl -e 'syswrite STDOUT, "e4\n" x 5000' | zsh: IOT instruction src/gnuchess --uci ``` This change fixes the crash by reading the correct amount of bytes. --- src/frontend/engine.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/frontend/engine.cc b/src/frontend/engine.cc index 85e15fb..e8fb3a2 100644 --- a/src/frontend/engine.cc +++ b/src/frontend/engine.cc @@ -514,15 +514,18 @@ void ForwardUserInputToEngine( void ) printf( "Error reading user input.\n" ); } else if ( userinputready > 0 ) { /* There are some data from the user. Read the data */ - strncpy( userinputaux, zerochar, BUF_SIZE ); - nread = read( STDIN_FILENO, userinputaux, BUF_SIZE ); - /* Send the data to the engine */ - assert( nread+1 < BUF_SIZE-1 ); - if ( strcmp(userinputaux,"quit") == 0 || strcmp(userinputaux,"quit\n") == 0 ) { - SET (flags, QUIT); + nread = read( STDIN_FILENO, userinputaux, BUF_SIZE-2 ); + if ( nread == -1 ) { + printf( "Error reading message from user.\n" ); + return; } + /* Send the data to the engine */ + assert( nread <= BUF_SIZE-2 ); userinputaux[nread] = '\n'; userinputaux[nread+1] = '\0'; + if ( strcmp(userinputaux,"quit\n") == 0 || strcmp(userinputaux,"quit\n\n") == 0 ) { + SET (flags, QUIT); + } int outError=0; int msg_count=0; msg_count = write( pipefd_a2e[1], userinputaux, nread+1 ); -- 2.39.5