From: Dmitry Shulga Date: February 5 2011 5:02am Subject: bzr commit into mysql-5.1 branch (Dmitry.Shulga:3577) Bug#57450 List-Archive: http://lists.mysql.com/commits/130488 X-Bug: 57450 Message-Id: <201102050502.p154PZC3028807@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============2372184834721044944==" --===============2372184834721044944== 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:luis.soares@stripped 3577 Dmitry Shulga 2011-02-05 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-05 05:02:00 +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-05 05:02:00 +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-05 05:02:00 +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-05 05:02:00 +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 # --===============2372184834721044944== 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\ # x15w33hb7pe64ixs # target_branch: file:///Users/shulga/projects/mysql/mysql-5.1-\ # bug57450/ # testament_sha1: 00a414842cb0c1bfbd285f2a4da74a18e11e6bba # timestamp: 2011-02-05 11:02:06 +0600 # base_revision_id: luis.soares@stripped\ # 34t52v63kxu7fqpx # # Begin bundle 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 SvtwlZwNpQvPs2aTSW9YT/F3JFOFCQuaCsVA --===============2372184834721044944==--