Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by [EMAIL PROTECTED]

http://bugzilla.ximian.com/show_bug.cgi?id=75263

--- shadow/75263        2005-06-14 12:30:31.000000000 -0400
+++ shadow/75263.tmp.4237       2005-06-14 12:30:31.000000000 -0400
@@ -0,0 +1,412 @@
+Bug#: 75263
+Product: Mono: Class Libraries
+Version: 1.0
+OS: 
+OS Details: SuSE 9.2
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Normal
+Component: Sys.Data
+AssignedTo: [EMAIL PROTECTED]                            
+ReportedBy: [EMAIL PROTECTED]               
+QAContact: [EMAIL PROTECTED]
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: OdbcDataReader.cs bug in GetPrimaryKeys() method
+
+Please fill in this template when reporting a bug, unless you know what 
+you are doing. 
+Description of Problem: 
+ 
+The bug in GetPrimaryKeys() for the following scenario: 
+ 
+1) A database table has a compound primary keys (two db columns make a row 
+unique). 
+2) Exercise Select query where the selected column in the query is not one 
+of the primary key combination. There is only one column is selected in 
+the query. 
+3) The bug in the GetPrimaryKeys() was allocated the returned keys string 
+array based on the number of returned columns in the Select statement up 
+front. In this scenario, the returned column is one, and the number of 
+primary keys in the table is two. The bug is in the while(true) section 
+while retrieving the number of primary fields from backend database. On 
+the second fetch of the second primary key, the keys[] array string crash 
+since it only being allocated one slot at the beginning. 
+4) attached is the diff -u of the OdbcDataReader.cs from tarball 1.1.7 
+with the latest from svn (retrieved about 11am June 13th 05). The fix was 
+not to make an assumption of keys[] string array to be allocated up front 
+based on the returned columns of the Select statement. There is a local 
+ArrayList object being introduced to dynamic add the primary keys fetched 
+from backend database. As the completion of the fetch, then the ArrayList 
+will convert and return an array of string. The signature of method 
+doesn't change. 
+5) here is the diff -u 
+5c5 
+< //   Brian Ritchie ([EMAIL PROTECTED]) 
+--- 
+> //   Brian Ritchie ([EMAIL PROTECTED])  
+23c23 
+< // 
+--- 
+> //  
+26c26 
+< // 
+--- 
+> //  
+92c92 
+<                 private CommandBehavior CommandBehavior 
+--- 
+>                 private CommandBehavior CommandBehavior  
+107c107 
+<                 protected override bool IsValidRow 
+--- 
+>                 protected override bool IsValidRow  
+225,226c225,226 
+<                              OdbcReturn 
+ret=libodbc.SQLDescribeCol(hstmt, Convert.ToUInt16(ordinal+1), 
+<                                      colname_buffer, bufsize, ref 
+colname_size, ref dt, ref ColSize, 
+--- 
+>                              OdbcReturn 
+ret=libodbc.SQLDescribeCol(hstmt, Convert.ToUInt16(ordinal+1),  
+>                                      colname_buffer, bufsize, ref 
+colname_size, ref dt, ref ColSize,  
+228c228 
+<                              if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo)) 
+--- 
+>                              if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo))  
+250c250 
+<                      if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo)) 
+--- 
+>                      if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo))  
+256,257c256,257 
+<                      ret = libodbc.SQLFreeHandle( (ushort) 
+OdbcHandleType.Stmt, hstmt); 
+<                      if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo)) 
+--- 
+>                      ret = libodbc.SQLFreeHandle( (ushort) 
+OdbcHandleType.Stmt, hstmt); 
+>                      if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo))  
+270c270 
+<              public 
+--- 
+>              public  
+279c279 
+<              public 
+--- 
+>              public  
+288c288 
+<              public 
+--- 
+>              public  
+300c300 
+<                         ret=libodbc.SQLGetData (hstmt, (ushort) 
+(ordinal+1), SQL_C_TYPE.BINARY, tbuff, length, 
+--- 
+>                         ret=libodbc.SQLGetData (hstmt, (ushort) 
+(ordinal+1), SQL_C_TYPE.BINARY, tbuff, length,  
+306c306 
+<                         if ( (ret != OdbcReturn.Success) && (ret != 
+OdbcReturn.SuccessWithInfo)) 
+--- 
+>                         if ( (ret != OdbcReturn.Success) && (ret != 
+OdbcReturn.SuccessWithInfo))  
+325c325 
+<                                         if (sqlstate != 
+libodbc.SQLSTATE_RIGHT_TRUNC) 
+--- 
+>                                         if (sqlstate != 
+libodbc.SQLSTATE_RIGHT_TRUNC)  
+346c346 
+<              public 
+--- 
+>              public  
+356c356 
+<              public 
+--- 
+>              public  
+367c367 
+<              public 
+--- 
+>              public  
+376c376 
+<              public 
+--- 
+>              public  
+389c389 
+<              public 
+--- 
+>              public  
+399c399 
+<              public 
+--- 
+>              public  
+408c408 
+<              public 
+--- 
+>              public  
+417c417 
+<              public 
+--- 
+>              public  
+426c426 
+<              public 
+--- 
+>              public  
+436c436 
+<              public 
+--- 
+>              public  
+445c445 
+<              public 
+--- 
+>              public  
+454c454 
+<              public 
+--- 
+>              public  
+463c463 
+<              public 
+--- 
+>              public  
+472c472 
+<              public 
+--- 
+>              public  
+481c481 
+<              public 
+--- 
+>              public  
+500c500 
+<                 DataTable GetSchemaTable() 
+--- 
+>                 DataTable GetSchemaTable()  
+502c502 
+<                         // FIXME : 
+--- 
+>                         // FIXME :  
+506c506 
+<                         // * Cache this DataTable so that it is not 
+contacting 
+--- 
+>                         // * Cache this DataTable so that it is not 
+contacting  
+510c510 
+<                      // Only Results from SQL SELECT Queries 
+--- 
+>                      // Only Results from SQL SELECT Queries  
+513c513 
+<                      if(cols.Length > 0) 
+--- 
+>                      if(cols.Length > 0)  
+546c546 
+<                              for (int i = 0; i < cols.Length; i += 1 ) 
+--- 
+>                              for (int i = 0; i < cols.Length; i += 1 )  
+599c599 
+<                                      // FIXME: according to Brian, 
+--- 
+>                                      // FIXME: according to Brian,  
+601c601 
+<                                      // however, we need it for Mono 
+--- 
+>                                      // however, we need it for Mono  
+611c611 
+<              public 
+--- 
+>              public  
+626c626 
+<              public 
+--- 
+>              public  
+651a652 
+>                                      case OdbcType.Numeric: 
+654,655c655 
+<                                              buffer=new 
+byte[bufsize];  // According to sqlext.h, use SQL_CHAR for decima. 
+<                                                 // 2005 03 10 : this now 
+works with unixodbc with numeric c type. 
+--- 
+>                                              buffer=new 
+byte[bufsize];  // According to sqlext.h, use SQL_CHAR for decimal.  
+657,661c657,660 
+<                                              byte[] temp = new 
+byte[outsize]; 
+<                                                 for (int 
+i=0;i<outsize;i++) 
+<                                                         
+temp[i]=buffer[i]; 
+<  
+<                                              if (outsize!=-1) 
+--- 
+>                                              if (outsize!=-1) { 
+>                                                      byte[] temp = new 
+byte[outsize]; 
+>                                                      for (int 
+i=0;i<outsize;i++) 
+>                                                              
+temp[i]=buffer[i]; 
+662a662 
+>                                              } 
+716c716 
+<                                                 if (outsize!=-1) // This 
+means SQL_NULL_DATA 
+--- 
+>                                                 if (outsize!=-1) // This 
+means SQL_NULL_DATA  
+739c739 
+<                              if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo)) 
+--- 
+>                              if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo))  
+742c742 
+<                              if (outsize==-1) // This means 
+SQL_NULL_DATA 
+--- 
+>                              if (outsize==-1) // This means 
+SQL_NULL_DATA  
+750c750 
+<              public 
+--- 
+>              public  
+823c823 
+<                      } 
+--- 
+>                      }        
+854,855c854,855 
+<                         ret = libodbc.SQLColAttribute (hstmt, column, 
+fieldId, 
+<                                                        buffer, 
+buffer.Length, 
+--- 
+>                         ret = libodbc.SQLColAttribute (hstmt, column, 
+fieldId,  
+>                                                        buffer, 
+buffer.Length,  
+872,873c872,873 
+<                         ret = libodbc.SQLColAttribute (hstmt, column, 
+fieldId, 
+<                                                        buffer, 
+buffer.Length, 
+--- 
+>                         ret = libodbc.SQLColAttribute (hstmt, column, 
+fieldId,  
+>                                                        buffer, 
+buffer.Length,  
+891,892c891 
+<                         //string [] keys = new string [cols.Length]; 
+<                                              string [] keys = null; 
+--- 
+>                         string [] keys = new string [cols.Length]; 
+894c893 
+<                         OdbcReturn ret = OdbcReturn.Error; 
+--- 
+>                         OdbcReturn ret = OdbcReturn.Error;                   
+896c895 
+<                                 
+ret=libodbc.SQLAllocHandle(OdbcHandleType.Stmt, 
+--- 
+>                                 
+ret=libodbc.SQLAllocHandle(OdbcHandleType.Stmt,  
+898c897 
+<                              if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo)) 
+--- 
+>                              if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo))  
+906,907c905,906 
+<                                 ret = libodbc.SQLPrimaryKeys (handle, 
+catalogName, -3, 
+<                                                               
+schemaName, -3, 
+--- 
+>                                 ret = libodbc.SQLPrimaryKeys (handle, 
+catalogName, -3,   
+>                                                               
+schemaName, -3,  
+919,922c918,919 
+<                                 //int i = 0; 
+<                                                              ArrayList 
+keysList = new ArrayList(); 
+<                                               
+<                                                              while 
+(true) { 
+--- 
+>                                 int i = 0;                               
+>                                 while (true) { 
+927,937c924,926 
+<                                          
+< 
+                                                                               
//keys 
+[i++] = pkey; 
+<                                                                              
+keysList.Add(pkey); 
+<                                                              } 
+<                                                               
+<                                                              
+if(keysList.Count > 0) { 
+<                                                                      
+keys = new string[keysList.Count]; 
+<                                                                      
+keysList.CopyTo(keys); 
+<                                                              } 
+<                                               
+<                                              } catch (OdbcException){ 
+--- 
+>                                         keys [i++] = pkey; 
+>                                 } 
+>                         } catch (OdbcException){ 
+940,941d928 
+<                                                              if(keys == 
+null) keys = new string[0]; 
+<                                               
+944c931 
+<                                         if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo)) 
+--- 
+>                                         if ((ret!=OdbcReturn.Success) && 
+(ret!=OdbcReturn.SuccessWithInfo))  
+948c935 
+<                                                 if 
+((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) 
+--- 
+>                                                 if 
+((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))  
+950c937 
+<                                 } 
+--- 
+>                                 }                              
+ 
+ 
+ 
+ 
+ 
+Steps to reproduce the problem: 
+1. A database table has a compound primary keys (in this case, two 
+database columns make a row unique). 
+2. Create an OdbcConnection, OdbcCommand and OdbcDataReader using UnixODBC 
+and MySQL-ODBC bridge to access MySQL database. Prepare a select statement 
+with returned column is not one of the primary key combination. There is 
+only column field retrieve in Select statement. 
+3. Execute OdbcDataReader(). 
+ 
+Actual Results: 
+keys[i++]=pkey on the second fetch causes keys[i++] overwrite memory since 
+keys[] is only being allocated one at beginning of the method. 
+ 
+Expected Results: 
+ 
+ 
+How often does this happen? 
+ 
+ 
+Additional Information:
_______________________________________________
mono-bugs maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-bugs

Reply via email to