在笔者的《修正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全局库。
该修正版本可以到这里下载:



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