| 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;
}
