Bug #4324 MySqlDataReader.GetBytes don't works correctly
Submitted: 29 Jun 2004 15:04 Modified: 9 Jul 2004 21:31
Reporter: Carsten Jendro Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version:0.76 / SourceCode OS:Any (All)
Assigned to: Reggie Burnett CPU Architecture:Any

[29 Jun 2004 15:04] Carsten Jendro
Description:
MySqlDataReader.GetBytes throws Index out of range exception

e.g.

GetBytes(2, 0, mybuffer, 0, int.MaxValue);

Length should be adjusted to the maximum length, but this dont works, because in this function the value of "fieldIndex" is not considred

see this code part

/*---------------------------------------------------------------------------*/
// adjust the length so we don't run off the end
if ( bufLen < (dataIndex+length)) 
{
    ...
}
/*---------------------------------------------------------------------------*/

Also a DOCUMENTED function is missing to get the size of a raw field in bytes, so i can't set the correct length in GetBytes manually

How to repeat:
see Description/Suggested fix

Suggested fix:
1)
Change code in DataReader.GetBytes

			// adjust the length so we don't run off the end
			if ( bufLen < (dataIndex+length)) 
			{
				length = (int)(bufLen - dataIndex); 
			}

2)
Add an info to the documentation that you can retrieve field length by passing NULL as value for "buffer"

3)
user Array.Copy() instead of for() to copy bytes from one array to an other

4)
It would be nice to have some new function like this in the MySqlDataReader:

/*---------------------------------------------------------------------------*/
        /// <summary>
        /// Reads a stream of bytes from the specified column offset into an array.
        /// </summary>
        /// <param name="i">The zero-based column ordinal. </param>
        /// <param name="length">The maximum length to copy into the buffer. </param>
        /// <returns>An array of byte.</returns>
        public byte[] GetBytes(int i, int length)
        {
            if (i >= _fields.Length) 
                throw new IndexOutOfRangeException();

            long bufLen = _fields[i].BufferLength;

            if (length <= 0) length = (int)bufLen+length;

            if (length < 0) length = 0;
            if (length > bufLen) length = (int)bufLen;

            byte[] bytes = _fields[i].Buffer;
            long fieldIndex = _fields[i].BufferIndex;

            byte[] result = new byte[length];

            Array.Copy(bytes,fieldIndex,result,0,length);

            return result;
        }

        /// <summary>
        /// Reads a stream of bytes from the specified column offset into an array.
        /// </summary>
        /// <param name="i">The zero-based column ordinal. </param>
        /// <returns>An array of byte.</returns>
        public byte[] GetBytes(int i)
        {
            return GetBytes(i,0);
        }
/*---------------------------------------------------------------------------*/
[9 Jul 2004 21:31] Reggie Burnett
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

> Length should be adjusted to the maximum length, but this dont works,
> because inthis function the value of "fieldIndex" is not considred

This is not true.  The length is returned from the function.

> Also a DOCUMENTED function is missing to get the size of a raw 
> field in bytes, so i can't set the correct length in GetBytes manually

I don't think any documented functions are missing.  You get the field size by passing null as the buffer refernece.