From: Dmitry Shulga Date: February 2 2011 11:38am Subject: bzr commit into mysql-5.1-bugteam branch (Dmitry.Shulga:3521) Bug#57450 List-Archive: http://lists.mysql.com/commits/130204 X-Bug: 57450 Message-Id: <201102021138.p1290k4C017787@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3080429514409217807==" --===============3080429514409217807== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///Users/shulga/projects/mysql/5.1-bugteam-bug57450/ based on revid:azundris@stripped 3521 Dmitry Shulga 2011-02-02 Fixed bug#57450 - mysql client enter in an infinite loop if the standard input is a directory. The problem is that mysql monitor try to read from stdin without checking input source type. The solution is to stop reading data from standard input if a call to read(2) failed. A new test case was added into mysql.test. @ client/my_readline.h Data members error and truncated was added to LINE_BUFFER structure. These data members used instead of out parameters in functions batch_readline, intern_read_line. @ client/mysql.cc read_and_execute() was modified: set status.exit_status to 1 when the error occured while reading the next command line in non-interactive mode. Also the value of the truncated attribute of structure LINE_BUFF is taken into account only for non-iteractive mode. @ client/readline.cc intern_read_line() was modified: cancel reading from input if fill_buffer() returns -1, e.g. if call to read failed. batch_readline was modified: set the error data member of LINE_BUFFER structure to value of my_errno when system error happened during call to my_read/my_realloc. @ mysql-test/t/mysql.test Test for bug#57450 was added. modified: client/my_readline.h client/mysql.cc client/readline.cc mysql-test/t/mysql.test === modified file 'client/my_readline.h' --- a/client/my_readline.h 2009-03-18 08:27:49 +0000 +++ b/client/my_readline.h 2011-02-02 11:38:28 +0000 @@ -25,9 +25,11 @@ typedef struct st_line_buffer uint eof; ulong max_size; ulong read_length; /* Length of last read string */ + int error; + bool truncated; } LINE_BUFFER; extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file); extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, char * str); -extern char *batch_readline(LINE_BUFFER *buffer, bool *truncated); +extern char *batch_readline(LINE_BUFFER *buffer); extern void batch_readline_end(LINE_BUFFER *buffer); === modified file 'client/mysql.cc' --- a/client/mysql.cc 2010-10-19 22:36:59 +0000 +++ b/client/mysql.cc 2011-02-02 11:38:28 +0000 @@ -1872,14 +1872,13 @@ static int read_and_execute(bool interac ulong line_number=0; bool ml_comment= 0; COMMANDS *com; - bool truncated= 0; status.exit_status=1; - + for (;;) { if (!interactive) { - line=batch_readline(status.line_buff, &truncated); + line=batch_readline(status.line_buff); /* Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF. Editors like "notepad" put this marker in @@ -1953,9 +1952,13 @@ static int read_and_execute(bool interac if (opt_outfile && line) fprintf(OUTFILE, "%s\n", line); } - if (!line) // End of file + // End of file or system error + if (!line) { - status.exit_status=0; + if (status.line_buff && status.line_buff->error) + status.exit_status= 1; + else + status.exit_status= 0; break; } @@ -1976,7 +1979,8 @@ static int read_and_execute(bool interac #endif continue; } - if (add_line(glob_buffer,line,&in_string,&ml_comment, truncated)) + if (add_line(glob_buffer, line, &in_string, &ml_comment, + status.line_buff ? status.line_buff->truncated : 0)) break; } /* if in batch mode, send last query even if it doesn't end with \g or go */ === modified file 'client/readline.cc' --- a/client/readline.cc 2009-03-18 08:27:49 +0000 +++ b/client/readline.cc 2011-02-02 11:38:28 +0000 @@ -24,7 +24,7 @@ static bool init_line_buffer(LINE_BUFFER ulong max_size); static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str); static size_t fill_buffer(LINE_BUFFER *buffer); -static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated); +static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length); LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) @@ -42,13 +42,12 @@ LINE_BUFFER *batch_readline_init(ulong m } -char *batch_readline(LINE_BUFFER *line_buff, bool *truncated) +char *batch_readline(LINE_BUFFER *line_buff) { char *pos; ulong out_length; - DBUG_ASSERT(truncated != NULL); - if (!(pos=intern_read_line(line_buff,&out_length, truncated))) + if (!(pos=intern_read_line(line_buff, &out_length))) return 0; if (out_length && pos[out_length-1] == '\n') if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */ @@ -162,7 +161,10 @@ static size_t fill_buffer(LINE_BUFFER *b if (!(buffer->buffer = (char*) my_realloc(buffer->buffer, buffer->bufread+1, MYF(MY_WME | MY_FAE)))) - return (uint) -1; + { + buffer->error= my_errno; + return (size_t) -1; + } buffer->start_of_line=buffer->buffer+start_offset; buffer->end=buffer->buffer+bufbytes; } @@ -177,7 +179,10 @@ static size_t fill_buffer(LINE_BUFFER *b /* Read in new stuff. */ if ((read_count= my_read(buffer->file, (uchar*) buffer->end, read_count, MYF(MY_WME))) == MY_FILE_ERROR) + { + buffer->error= my_errno; return (size_t) -1; + } DBUG_PRINT("fill_buff", ("Got %lu bytes", (ulong) read_count)); @@ -198,8 +203,7 @@ static size_t fill_buffer(LINE_BUFFER *b } - -char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated) +char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length) { char *pos; size_t length; @@ -214,22 +218,25 @@ char *intern_read_line(LINE_BUFFER *buff if (pos == buffer->end) { /* - fill_buffer() can return 0 either on EOF in which case we abort - or when the internal buffer has hit the size limit. In the latter case - return what we have read so far and signal string truncation. + fill_buffer() can return NULL on EOF (in which case we abort), + on error, or when the internal buffer has hit the size limit. + In the latter case return what we have read so far and signal + string truncation. */ - if (!(length=fill_buffer(buffer)) || length == (uint) -1) + if (!(length= fill_buffer(buffer))) { if (buffer->eof) DBUG_RETURN(0); } + else if (length == (size_t) -1) + DBUG_RETURN(NULL); else continue; pos--; /* break line here */ - *truncated= 1; + buffer->truncated= 1; } else - *truncated= 0; + buffer->truncated= 0; buffer->end_of_line=pos+1; *out_length=(ulong) (pos + 1 - buffer->eof - buffer->start_of_line); DBUG_RETURN(buffer->start_of_line); === modified file 'mysql-test/t/mysql.test' --- a/mysql-test/t/mysql.test 2009-12-17 20:06:36 +0000 +++ b/mysql-test/t/mysql.test 2011-02-02 11:38:28 +0000 @@ -412,5 +412,11 @@ drop table t1; --echo --exec $MYSQL --skip-column-names --vertical test -e "select 1 as a" +# +# Bug#57450: mysql client enter in an infinite loop if the standard input is a directory +# +--error 1 +--exec $MYSQL < . + --echo --echo End of tests --===============3080429514409217807== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/dmitry.shulga@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: dmitry.shulga@stripped\ # mh3k8j6lgvu3m05z # target_branch: file:///Users/shulga/projects/mysql/5.1-bugteam-\ # bug57450/ # testament_sha1: 6e78a48228923d389af9ad5ea6ae2b0d19b826a5 # timestamp: 2011-02-02 17:38:35 +0600 # base_revision_id: azundris@stripped # # Begin bundle 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 5GeAb/F3JFOFCQNbVC9Q --===============3080429514409217807==--