修正Firebird Net Provider 1.7“偏移和长度已超出数组界限”BUG(提供下载)

 

        在笔者的《修正Firebird Net Provider 1.7中文路径BUG(提供下载)》一文中,笔者基于从Firebird官方网站下载的最新源码,修正了Firebird Net Provider 1.7连接嵌入式版本的中文路径BUG,但最近在将系统切换到Server版本时,却遇到了“偏移和长度已超出数组界限”的错误。如下:

 

仔细分析“堆栈跟踪”详细信息,发现.NET调用调试信息最上两行已经提示了异常发生的位置,如下:
 
System.Buffer.BlockCopy(Array src, Int32 srcOffset, Array dst, Int32 dstOffset, Int32 count) +0
FirebirdSql.Data.Gds.GdsDatabase.DatabaseInfo(Byte[] items, Byte[] buffer, Int32 bufferLength) +176
 
从该信息中我们可以看出,是FirebirdSql.Data.Gds.GdsDatabase.DatabaseInfo函数调用System.Buffer.BlockCopy时发生了越界异常。
那我们打开FirebirdSql.Data.Gds.GdsDatabase的源文件,找到DatabaseInfo函数的实现部分:
private void DatabaseInfo(byte[] items, byte[] buffer, int bufferLength)
{
       lock (this)
       {
              try
              {
                     // see src/remote/protocol.h for packet definition (p_info struct)             
                     this.Send.Write(IscCodes.op_info_database);      //     operation
                     this.Send.Write(this.handle);                       //     db_handle
                     this.Send.Write(0);                                           //     incarnation
                     this.Send.WriteBuffer(items, items.Length); //     items
                     this.Send.Write(bufferLength);                           //     result buffer length
                     this.Send.Flush();
                     GdsResponse r = this.ReadGenericResponse();
                     Buffer.BlockCopy(r.Data, 0, buffer, 0, bufferLength); //此行抛出了异常
              }
              catch (IOException)
              {
                     throw new IscException(IscCodes.isc_network_error);
              }
       }
}
 
那我们来看看抛出异常的这行代码,Buffer.BlockCopy函数,是.NET环境提供的平台函数,其参数说明如下:
public static void BlockCopy(
   Array src, //源缓冲区。
   int srcOffset, //src 的字节偏移量。
   Array dst, //目标缓冲区。
   int dstOffset, //dst 的字节偏移量。
   int count//要复制的字节数。
);
根据异常提示,我们可以初步断定,是count参数的值超过了源缓冲区的数组长度,那么,我们很容易就能找出原因:bufferLength超出了r.Data的长度,那既然参数中两个偏移量都是0,那么我们可以使用r.Data.Length来代替bufferLength,以避免bufferLength与r.Data长度不匹配的问题。
即,将此语句更改为Buffer.BlockCopy(r.Data, 0, buffer, 0, r.Data.Length);
修改完毕,编译执行,问题顺利解决。
注意:升级该dll时,请删除系统assambly目录中的FirebirdSql.Data.Firebird全局库。
该修正版本可以到这里下载:
 
 
 
 
标签:
文章分类 FK Coding
1 条评论在 “修正Firebird Net Provider 1.7“偏移和长度已超出数组界限”BUG(提供下载)” 上
  1. circulatory 说道:

    Oh my goodness! a tremendous article dude. Thank you Nonetheless I am experiencing issue with ur rss . Don’t know why Unable to subscribe to it. Is there anyone getting similar rss downside? Anyone who is aware of kindly respond. Thnkx

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

点赞
如果您觉得很赞,我将非常乐意接受虚拟币的捐赠,以示您对我的肯定。

比特币钱包地址:
1PqpqA8FyH3NbfCrbcRd1YxQk3LEsSEYDV
莱特币钱包地址:
LRTdmovGGVEHCKWz7JdL9aiB7VZkuNycJf
站点勋章
网站统计