From: Dmitry Shulga Date: February 4 2011 9:59am Subject: bzr commit into mysql-5.1 branch (Dmitry.Shulga:3576) Bug#57450 List-Archive: http://lists.mysql.com/commits/130379 X-Bug: 57450 Message-Id: <201102040959.p149nqPq004400@rcsinet13.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============5757991904613600710==" --===============5757991904613600710== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///Users/shulga/projects/mysql/mysql-5.1-bug57450/ based on revid:dmitry.shulga@stripped 3576 Dmitry Shulga 2011-02-04 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-04 09:59:17 +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-11-26 13:57:59 +0000 +++ b/client/mysql.cc 2011-02-04 09:59:17 +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-04 09:59:17 +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 2010-12-01 06:55:31 +0000 +++ b/mysql-test/t/mysql.test 2011-02-04 09:59:17 +0000 @@ -412,6 +412,12 @@ 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 # --===============5757991904613600710== 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\ # 5uhegfasckz7kcg0 # target_branch: file:///Users/shulga/projects/mysql/mysql-5.1-\ # bug57450/ # testament_sha1: 943d098ba43e0ae2f246b6d0a4b5983efa0c9040 # timestamp: 2011-02-04 15:59:24 +0600 # base_revision_id: dmitry.shulga@stripped\ # sakc2ctbjb9n7tqv # # Begin bundle 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 cKEhUpiUSA== --===============5757991904613600710==--