在笔者的《修正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