Chúng tôi có một ứng dụng WinForms AnyCPU trong đó một điều khiển thư viện nhà cung cấp thỉnh thoảng ném ngoại lệ sau đây trên hộp của người dùng 64-bit chạy nhiều màn hình:OverflowException không giải thích được đúc IntPtr đại diện màn hình phối hợp để Int32
System.OverflowException: Arithmetic operation resulted in an overflow.
at VendorLibraryName.VendorControl.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
tôi đã nhìn vào xử lý WndProc thư viện nhà cung cấp kiểm soát, và các bit duy nhất của mã mà có vẻ như nó có thể tạo ra một tràn là thế này (ý kiến của tôi - điều này được dịch ngược):
switch (msg)
{
case 132: // NCHITTEST
case 672: // NCMOUSEHOVER
// Technically dangerous: convert IntPtr to Int32 in a 64-bit process.
// However, note that for these message codes,
// LParam represents a "packed" x and y screen-coordinate.
// Given my understanding of how this packing occurs, I can't think
// of how to construct an LParam such that it would overflow an Int32.
SomeMethod(x: (int)m.LParam & 65535, y: (int)m.LParam >> 16);
// More code...
đây là IL thực tế cho các chuyển đổi và bit-twiddlin g:
IL_0092: ldarg.1
IL_0093: call instance native int [System.Windows.Forms]System.Windows.Forms.Message::get_LParam()
// As far as I can tell, this is the only instruction on which overflow could occur
IL_0098: call int32 [mscorlib]System.IntPtr::op_Explicit(native int)
IL_009d: ldc.i4 65535
IL_00a2: and
IL_00a3: ldarg.1
// Same thing here...
IL_00a4: call instance native int [System.Windows.Forms]System.Windows.Forms.Message::get_LParam()
IL_00a9: call int32 [mscorlib]System.IntPtr::op_Explicit(native int)
IL_00ae: ldc.i4.s 16
IL_00b0: shr
Rõ ràng, quy trình này có vẻ dễ bị các vấn đề tràn khi có chuyển đổi Message.LParam (IntPtr) sang Int32 trong quy trình 64 bit. Trong thực tế, thói quen này là sai ở chỗ nó không đối phó với các tọa độ âm một cách chính xác - có vẻ như một cổng không chính xác của các cửa sổ GET_X_LPARAM và GET_Y_PARAM macro đến C#.
Tuy nhiên, tôi không thể xem LParam có thể được xây dựng như thế nào cho NCHITTEST/NCMOUSEHOVER, trong thực tế, sẽ tràn phạm vi Int32. (I nghĩ rằng 16 bit thấp hơn bao gồm đã ký phối hợp 16 bit X và các bit còn lại bao gồm toạ độ Y 16-bit mở rộng. Hãy sửa tôi nếu sai vì đây có thể là một sự hiểu lầm quan trọng) .
Tôi không thể tạo lại ngoại lệ trên hộp dev của mình với nhiều cấu hình màn hình và vị trí cửa sổ khác nhau.
Điều phối màn hình nào thực sự có thể dẫn đến tràn ở đây? Hoặc là có cách nào khác khối này có thể dẫn đến một tràn?
Thậm chí nếu bạn don' t tìm hiểu lý do tại sao các thông số tràn, chuyển đổi mù của IntPtr để Int32 rõ ràng là một lỗi trong thư viện. Microsoft chỉ đảm bảo những gì được ghi lại, nó không đảm bảo bất cứ điều gì về các bit không có giấy tờ. Bạn nên liên hệ với nhà cung cấp để sửa lỗi –
@Simon: Đúng vậy. Nhà cung cấp này đã không được nhắc nhở với các sửa lỗi trong quá khứ mặc dù; vì vậy tôi hy vọng rằng sẽ mất thời gian. Trong khi đó, tôi muốn xác định những gì * chính xác * kích hoạt ngoại lệ trong sản xuất để chúng tôi có thể hướng dẫn người dùng cách làm việc xung quanh nó. Trung hạn, chúng tôi có thể sẽ đưa ra một số cách giải quyết trong mã ứng dụng của mình. Đầu tiên, tôi cần một repro! – Ani
Hmmm ... có thể nó có thể liên quan đến kích thước màn hình ảo không? Chỉ có một điều tôi có thể nghĩ rằng điều đó sẽ tràn đúng ... – JerKimball