Skip to content

Commit d1a6e6a

Browse files
authored
Fix nested type builder ownership (#141)
1 parent bd8bec1 commit d1a6e6a

5 files changed

Lines changed: 114 additions & 13 deletions

File tree

‎Handle/BNEnumerationBuilder.cs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ internal static EnumerationBuilder MustBorrowHandle(IntPtr handle)
6767

6868
return new EnumerationBuilder(handle, false);
6969
}
70+
71+
internal void TransferOwnershipToCore()
72+
{
73+
this.SetHandle(IntPtr.Zero);
74+
this.SetHandleAsInvalid();
75+
}
7076

7177
protected override bool ReleaseHandle()
7278
{
@@ -165,4 +171,4 @@ public Enumeration Build()
165171
}
166172

167173

168-
}
174+
}

‎Handle/BNNamedTypeReferenceBuilder.cs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ internal static NamedTypeReferenceBuilder MustBorrowHandle(IntPtr handle)
8181

8282
return new NamedTypeReferenceBuilder(handle, false);
8383
}
84+
85+
internal void TransferOwnershipToCore()
86+
{
87+
this.SetHandle(IntPtr.Zero);
88+
this.SetHandleAsInvalid();
89+
}
8490

8591
/// <summary>
8692
/// Releases the native BNNamedTypeReferenceBuilder handle when this instance is disposed or finalized.
@@ -156,4 +162,4 @@ public void SetName(QualifiedName name)
156162
);
157163
}
158164
}
159-
}
165+
}

‎Handle/BNStructureBuilder.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ internal static StructureBuilder MustBorrowHandle(IntPtr handle)
9494

9595
return new StructureBuilder(handle, false);
9696
}
97+
98+
internal void TransferOwnershipToCore()
99+
{
100+
this.SetHandle(IntPtr.Zero);
101+
this.SetHandleAsInvalid();
102+
}
97103

98104
protected override bool ReleaseHandle()
99105
{

‎Handle/BNTypeBuilder.cs‎

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace BinaryNinja
77
{
8-
public class TypeBuilder : AbstractSafeHandle<TypeBuilder>
8+
public partial class TypeBuilder : AbstractSafeHandle<TypeBuilder>
99
{
1010
internal TypeBuilder(IntPtr handle , bool owner)
1111
: base(handle , owner)
@@ -81,6 +81,7 @@ public static TypeBuilder CreateStructureType(Structure structure)
8181
/// </summary>
8282
/// <param name="builder">The structure builder to create a type builder from.</param>
8383
/// <returns>A new owned TypeBuilder for the structure type.</returns>
84+
/// <remarks>The core takes ownership and invalidates <paramref name="builder"/>.</remarks>
8485
public static TypeBuilder CreateStructureTypeWithBuilder(StructureBuilder builder)
8586
{
8687
// 1. Validate the required builder parameter.
@@ -90,9 +91,13 @@ public static TypeBuilder CreateStructureTypeWithBuilder(StructureBuilder builde
9091
}
9192

9293
// 2. Create a structure type builder from the builder; the returned handle is owned.
93-
return TypeBuilder.MustTakeHandle(
94-
NativeMethods.BNCreateStructureTypeBuilderWithBuilder(builder.DangerousGetHandle())
95-
);
94+
IntPtr handle = NativeMethods.BNCreateStructureTypeBuilderWithBuilder(
95+
builder.DangerousGetHandle()
96+
);
97+
TypeBuilder result = TypeBuilder.MustTakeHandle(handle);
98+
builder.TransferOwnershipToCore();
99+
100+
return result;
96101
}
97102

98103
/// <summary>
@@ -713,6 +718,7 @@ public void SetIntegerTypeDisplayType(IntegerDisplayType displayType)
713718
/// <param name="width">The width of the enumeration type in bytes.</param>
714719
/// <param name="isSigned">The signedness with confidence.</param>
715720
/// <returns>A new owned TypeBuilder for the enumeration type.</returns>
721+
/// <remarks>The core takes ownership and invalidates <paramref name="builder"/>.</remarks>
716722
public static unsafe TypeBuilder CreateEnumerationTypeWithBuilder(
717723
Architecture arch ,
718724
EnumerationBuilder builder ,
@@ -735,14 +741,16 @@ BoolWithConfidence isSigned
735741
BNBoolWithConfidence nativeSigned = isSigned.ToNative();
736742

737743
// 3. Create an enumeration type builder from the builder; the returned handle is owned.
738-
return TypeBuilder.MustTakeHandle(
739-
NativeMethods.BNCreateEnumerationTypeBuilderWithBuilder(
744+
IntPtr handle = NativeMethods.BNCreateEnumerationTypeBuilderWithBuilder(
740745
arch.DangerousGetHandle() ,
741746
builder.DangerousGetHandle() ,
742747
width ,
743748
(IntPtr)(&nativeSigned)
744-
)
745-
);
749+
);
750+
TypeBuilder result = TypeBuilder.MustTakeHandle(handle);
751+
builder.TransferOwnershipToCore();
752+
753+
return result;
746754
}
747755

748756
/// <summary>
@@ -815,6 +823,7 @@ BinaryNinja.Type type
815823
/// <param name="cnst">The const qualifier with confidence.</param>
816824
/// <param name="vltl">The volatile qualifier with confidence.</param>
817825
/// <returns>A new owned TypeBuilder for the named type reference.</returns>
826+
/// <remarks>The core takes ownership and invalidates <paramref name="builder"/>.</remarks>
818827
public static unsafe TypeBuilder CreateNamedTypeReferenceBuilderWithBuilder(
819828
NamedTypeReferenceBuilder builder ,
820829
ulong width ,
@@ -834,15 +843,18 @@ BoolWithConfidence vltl
834843
BNBoolWithConfidence nativeVltl = vltl.ToNative();
835844

836845
// 3. Create the builder; the returned handle is owned.
837-
return TypeBuilder.MustTakeHandle(
846+
IntPtr handle =
838847
NativeMethods.BNCreateNamedTypeReferenceBuilderWithBuilder(
839848
builder.DangerousGetHandle() ,
840849
width ,
841850
align ,
842851
(IntPtr)(&nativeCnst) ,
843852
(IntPtr)(&nativeVltl)
844-
)
845-
);
853+
);
854+
TypeBuilder result = TypeBuilder.MustTakeHandle(handle);
855+
builder.TransferOwnershipToCore();
856+
857+
return result;
846858
}
847859

848860
/// <summary>

‎Handle/BNTypeBuilderComposition.cs‎

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System;
2+
3+
namespace BinaryNinja
4+
{
5+
public partial class TypeBuilder
6+
{
7+
/// <summary>Finalizes this generic builder into an immutable type.</summary>
8+
public BinaryNinja.Type FinalizeType()
9+
{
10+
return BinaryNinja.Type.MustTakeHandle(
11+
NativeMethods.BNFinalizeTypeBuilder(this.handle)
12+
);
13+
}
14+
15+
/// <summary>Replaces the mutable structure owned by this type builder.</summary>
16+
/// <remarks>
17+
/// The core takes ownership and invalidates <paramref name="builder"/>.
18+
/// </remarks>
19+
public void SetStructureBuilder(StructureBuilder builder)
20+
{
21+
if (null == builder)
22+
{
23+
throw new ArgumentNullException(nameof(builder));
24+
}
25+
26+
NativeMethods.BNSetStructureBuilder(
27+
this.handle,
28+
builder.DangerousGetHandle()
29+
);
30+
builder.TransferOwnershipToCore();
31+
}
32+
33+
/// <summary>Replaces the mutable enumeration owned by this type builder.</summary>
34+
/// <remarks>
35+
/// The core takes ownership and invalidates <paramref name="builder"/>.
36+
/// </remarks>
37+
public void SetEnumerationBuilder(EnumerationBuilder builder)
38+
{
39+
if (null == builder)
40+
{
41+
throw new ArgumentNullException(nameof(builder));
42+
}
43+
44+
NativeMethods.BNSetEnumerationBuilder(
45+
this.handle,
46+
builder.DangerousGetHandle()
47+
);
48+
builder.TransferOwnershipToCore();
49+
}
50+
51+
/// <summary>Replaces the mutable named reference owned by this type builder.</summary>
52+
/// <remarks>
53+
/// The core takes ownership and invalidates <paramref name="builder"/>.
54+
/// </remarks>
55+
public void SetNamedTypeReferenceBuilder(
56+
NamedTypeReferenceBuilder builder
57+
)
58+
{
59+
if (null == builder)
60+
{
61+
throw new ArgumentNullException(nameof(builder));
62+
}
63+
64+
NativeMethods.BNSetNamedTypeReferenceBuilder(
65+
this.handle,
66+
builder.DangerousGetHandle()
67+
);
68+
builder.TransferOwnershipToCore();
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)