Bug #44960 | backslash in string - connector return exeption | ||
---|---|---|---|
Submitted: | 19 May 2009 18:46 | Modified: | 26 May 2009 13:18 |
Reporter: | Moshe Lampert | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Connector / NET | Severity: | S3 (Non-critical) |
Version: | 6.0.3 | OS: | Any |
Assigned to: | Vladislav Vaintroub | CPU Architecture: | Any |
Tags: | regression |
[19 May 2009 18:46]
Moshe Lampert
[20 May 2009 8:04]
Tonci Grgin
Hi Moshe and thanks for your report. I would like to see compact but complete test case attached as well as MySQL server info and my.ini file.
[20 May 2009 8:36]
Tonci Grgin
Bug#44973 was marked as duplicate of this report.
[20 May 2009 8:43]
Moshe Lampert
MySQL Version: 5.1.30-2 (@debian) Connector Version: 6.0.3 MySQL Encoding: utf-8 Using Conn As New MySqlConnection(...) Conn.Open() Dim Cmd As new MySQLCommand("",Conn) Cmd.CommandText="insert into pb_im set m_from=1, m_to=1, m_content='\\=';" Cmd.ExecuteNonQuery() End Using ' and close/dispose the connection
[20 May 2009 8:47]
Tonci Grgin
Moshe, please please attach *full* test case. Not only am I missing DDL/DML statements but also a connection string...
[20 May 2009 10:44]
Moshe Lampert
connstring: server=*;user id=*; password=*; database=*; pooling=true; Min Pool Size=40;Max Pool Size=150; Connect Timeout=5;default command timeout=10 There is no other code, as my testcase is simple SQL queries (in this code - some small ASHX code).
[20 May 2009 12:17]
Tonci Grgin
Ok, this test case: MySqlConnection con = new MySqlConnection(); con.ConnectionString = "DataSource=**;Database=test;UserID=**;Password=**;PORT=**;logging=True;"; con.Open(); MySqlCommand cmdCreateTable = new MySqlCommand("DROP TABLE IF EXISTS bug44973", con); cmdCreateTable.ExecuteNonQuery(); cmdCreateTable.CommandText = "CREATE TABLE `bug44973`(`ID` int UNSIGNED NOT NULL auto_increment, `file_name` varchar(256) COLLATE latin1_bin NOT NULL, PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"; cmdCreateTable.ExecuteNonQuery(); string query = "INSERT INTO bug44973 VALUES (NULL, '2bsl=\\-1bsl=\')"; cmdCreateTable.CommandText = query; Assert.AreEqual(1, cmdCreateTable.ExecuteNonQuery()); cmdCreateTable.Dispose(); con.Close(); con.Dispose(); produces following output: [20.5.2009 14:10:45] - Executing command QUERY with text ='SHOW VARIABLES' [20.5.2009 14:10:45] - Executing command QUERY with text ='SHOW COLLATION' [20.5.2009 14:10:45] - Executing command QUERY with text ='SET NAMES utf8;SET character_set_results=NULL' [20.5.2009 14:10:46] - Executing command QUERY with text ='DROP TABLE IF EXISTS bug44973' [20.5.2009 14:10:46] - Executing command QUERY with text ='CREATE TABLE `bug44973`(`ID` int UNSIGNED NOT NULL auto_increment, `file_name` varchar(256) COLLATE latin1_bin NOT NULL, PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin' [20.5.2009 14:10:46] - Executing command QUERY with text ='INSERT INTO bug44973 VALUES (NULL, '2bsl=\-1bsl=')' <<<< So, I did not get any crashes but what I see appears as regression from Bug#4505 to me. Adding reference to Bug#44973 too.
[20 May 2009 12:55]
Alexander Sosedkin
Look for the string that you want to insert '2bsl=\\-1bsl=\' and a string in the output '2bsl=\-1bsl=', I think you can see the difference? Or change in the your test сase, for insert a string '\\', which should insert a backslash, you get an exception: System.ArgumentOutOfRangeException: Index and length must refer to a location within the string. Parameter name: length
[20 May 2009 13:05]
Tonci Grgin
Alexander, of course I see :) And as for later part (inserting '\\') I made reference to your bug.
[20 May 2009 13:11]
Alexander Sosedkin
OK :) Thank you!
[21 May 2009 8:05]
Alexander Sosedkin
I rushed to the conclusion, then that variable is "escaped" is not needed. In my opinion code "MySqlTokenizer.ReadQuotedToken" should look like: private void ReadQuotedToken(char quoteChar) { startIndex = pos-1; bool escaped = false; while (pos < sql.Length) { char c = sql[pos]; if (escaped) escaped = false; else if (c == quoteChar) break; else if (c == '\\' && BackslashEscapes) escaped = true; pos++; } pos++; Quoted = true; stopIndex = pos; } If this can help you.
[21 May 2009 8:13]
Tonci Grgin
Alexander, thanks for your contribution.
[22 May 2009 21:45]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/74815
[22 May 2009 21:46]
Reggie Burnett
fixed in 6.0.4
[26 May 2009 13:18]
Tony Bedford
An entry was added to the 6.0.4 changelog: A SQL query string containing an escaped backslash caused an exception to be generated: Index and length must refer to a location within the string. Parameter name: length at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy) at MySql.Data.MySqlClient.MySqlTokenizer.NextParameter() at MySql.Data.MySqlClient.Statement.InternalBindParameters(String sql, MySqlParameterCollection parameters, MySqlPacket packet) at MySql.Data.MySqlClient.Statement.BindParameters() at MySql.Data.MySqlClient.PreparableStatement.Execute() at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
[5 Aug 2009 4:29]
Dennis Haney
It seems the actual bug wasnt really fixed... public string NextParameter() { while (this.FindToken()) { if ((this.stopIndex - this.startIndex) >= 2) { this.sql.Substring(this.startIndex, this.stopIndex - this.startIndex).Trim(); <----- what on earth does this line do :D char ch = this.sql[this.startIndex]; char ch2 = this.sql[this.startIndex + 1]; if ((ch == '?') || ((ch == '@') && (ch2 != '@'))) { return this.sql.Substring(this.startIndex, this.stopIndex - this.startIndex); } } } return null; }