Skip to content

[Regression] [0.3.162] Arithmetic overflow when casting IntPtr to void* #1412

@trympet

Description

@trympet

Hello! I encountered a bug after updating to the latest version. I traced the regression back to 0.3.162.

Actual behavior

Passing a negative value, e.g. -1, as an IntPtr to a struct backed by a void* throws a System.OverflowException when the CheckForOverflowUnderflow build property is true.

Expected behavior

A blittable struct that accepts an IntPtr in the constructor should accept any value in the IntPtr domain, even when CheckForOverflowUnderflow is set. This invariant seems to hold before 0.3.162.

Repro steps

  1. NativeMethods.txt content:
HWND
  1. NativeMethods.json content (if present):
{
  "$schema": "https://aka.ms/CsWin32.schema.json",
  "emitSingleFile": false,
  "allowMarshaling": false,
  "public": true,
  "useSafeHandles": false
}
  1. Program.cs:
_ = new HWND(new IntPtr(-3))
  1. dotnet run /p:CheckForOverflowUnderflow=true

Context

The LKG (0.3.106) would generate a struct like so

[DebuggerDisplay("{Value}")]
[global::System.CodeDom.Compiler.GeneratedCode("Microsoft.Windows.CsWin32", "0.3.106+a37a0b4b70")]
public readonly partial struct HWND
  : IEquatable<HWND>
{
  public readonly IntPtr Value;

  public HWND(IntPtr value) => this.Value = value;
}

however, the latest generates a struct where the IntPtr is cast to a void* without wrapping it in an unchecked expression.

[DebuggerDisplay("{Value}")]
[global::System.CodeDom.Compiler.GeneratedCode("Microsoft.Windows.CsWin32", "0.3.162+1beb6ff56f.RR")]
public unsafe readonly partial struct HWND
    : IEquatable<HWND>
{
  public readonly void* Value;

  public HWND(void* value) => this.Value = value;

  public HWND(IntPtr value):this((void*)value)
  {
  }
}

Hence, the exception:

Image

I think an easy fix would be to wrap the cast in an unchecked expression :-)

  • CsWin32 version: 0.3.162
  • Target Framework: net9.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions