Skip to content

fix: EnumerationType member signedness (Type.Signed + ConvertInteger)#23

Merged
tinysec merged 1 commit into
masterfrom
fix/enumeration-member-signedness
Jul 8, 2026
Merged

fix: EnumerationType member signedness (Type.Signed + ConvertInteger)#23
tinysec merged 1 commit into
masterfrom
fix/enumeration-member-signedness

Conversation

@tinysec

@tinysec tinysec commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Summary

Python's EnumerationType.members reinterprets each member's raw u64 per the type's signedness and width (binaryninja.types.convert_integer), so a signed enum reports -1 for 0xFFFFFFFFFFFFFFFF. The C# binding only exposed the raw EnumerationMember.Value (ulong), so signed enumerations appeared as huge unsigned numbers.

  • Type.Signed — wraps BNIsTypeSigned (BoolWithConfidence). Width already existed.
  • EnumerationType.GetMemberSignedValues() — returns each member value run through the width-mask + signed-reinterpret conversion that mirrors convert_integer. The raw EnumerationMember.Value stays ulong (the low-level C value); the signed view is opt-in via the parity method.

The minimal durable-layer fix per the parity audit (the alternative — changing EnumerationMember.Value to a signed type — would break existing API).

Verification

  • Binding builds clean (0 warnings, 0 errors).
  • New E2E tests: build signed/unsigned/narrow-width enums via EnumerationBuilder and assert GetMemberSignedValues sign-extends (0xFF..F → -1 for width 1 and 8) while preserving a small unsigned value. EnumerationMember.Value (raw) is checked alongside.

Python's EnumerationType.members reinterprets each member's raw u64 per the
type's signedness and width (binaryninja.types.convert_integer), so a signed
enum reports -1 for 0xFFFFFFFFFFFFFFFF. The C# binding only exposed the raw
EnumerationMember.Value (ulong), so signed enumerations appeared as huge
unsigned numbers.

- Type.Signed: wrap BNIsTypeSigned (BoolWithConfidence). Width already existed.
- EnumerationType.GetMemberSignedValues(): return each member value run through
  the width-mask + signed-reinterpret conversion that mirrors convert_integer.
  The raw EnumerationMember.Value stays ulong (the low-level C value); the
  signed view is opt-in via the parity method.
@tinysec tinysec merged commit 492c4b4 into master Jul 8, 2026
1 check passed
@tinysec tinysec deleted the fix/enumeration-member-signedness branch July 8, 2026 05:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant