Skip to content

Commit 415b2dd

Browse files
authored
[runtime] Fix skipping nested struct types when processing method type encodings. Fixes #22837. (#22859)
Fix skipping consecutive nested structs (such as `"{CGPoint=dd}{CGSize=dd}"` inside `"{CGRect={CGPoint=dd}{CGSize=dd}}"`) by keep looping once the first nested struct is found. Fixes #22837.
1 parent 139e493 commit 415b2dd

File tree

6 files changed

+81
-1
lines changed

6 files changed

+81
-1
lines changed

runtime/trampolines.m

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@
428428
// Example:
429429
// {bc}d => d
430430
// {a{b}cd}e => e
431+
// {CGRect={CGPoint=dd}{CGSize=dd}}e =>
431432
static const char *
432433
skip_nested_brace (const char *type)
433434
{
@@ -436,7 +437,8 @@
436437
while (*++type) {
437438
switch (*type) {
438439
case '{':
439-
return skip_nested_brace (type);
440+
type = skip_nested_brace (type);
441+
break;
440442
case '}':
441443
return type++;
442444
default:
@@ -455,11 +457,14 @@
455457
// {CGRect=dddd} => dddd
456458
// ^q => ^
457459
// @? => @ (this is a block)
460+
// ^{CGRect={CGPoint=dd}{CGSize=dd}} => ^
458461
//
459462
// type: the input type name
460463
// struct_name: where to write the collapsed struct name. Returns an empty string if the array isn't big enough.
461464
// max_char: the maximum number of characters to write to struct_name
462465
// return value: false if something went wrong (an exception thrown, or struct_name wasn't big enough).
466+
//
467+
// There's a unit test for this method in monotouch-test (in NativeRuntimeTest.cs)
463468
bool
464469
xamarin_collapse_struct_name (const char *type, char struct_name[], int max_char, GCHandle *exception_gchandle)
465470
{

tests/bindings-test/ApiDefinition.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,9 @@ interface ObjCProtocolTest {
316316

317317
[Export ("methodEncodings:obj2:obj3:obj4:obj5:obj6:obj7:")]
318318
void GetMethodEncodings (ref NSObject obj1, ref NSObject obj2, ref NSObject obj3, ref NSObject obj4, ref NSObject obj5, ref NSObject obj6, ref NSObject obj7);
319+
320+
[Export ("setPtrPropertyCGRect:p2:p3:p4:p5:p6:")]
321+
void SetPtrPropertyCGRect (nint p1, nint p2, nint p3, nint p4, ref global::CoreGraphics.CGRect p5, nint p6);
319322
}
320323

321324
[Protocol]

tests/monotouch-test/ObjCRuntime/Messaging.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ public struct objc_super {
244244

245245
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
246246
public extern static void void_objc_msgSend_out_byte_out_sbyte_out_short_out_ushort_out_int_out_uint_out_long_out_ulong (IntPtr receiver, IntPtr selector, out EnumB b, out EnumSB sb, out EnumS s, out EnumUS us, out EnumI i, out EnumUI ui, out EnumL l, out EnumUL ul);
247+
248+
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
249+
public extern static void void_objc_msgSend_IntPtr_IntPtr_IntPtr_IntPtr_CGRect_IntPtr (IntPtr receiver, IntPtr selector, IntPtr p1, IntPtr p2, IntPtr p3, IntPtr p4, ref CGRect p5, IntPtr p6);
247250
}
248251

249252
public enum EnumB : byte { a, b = 10 };
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using System.Text;
4+
5+
using Foundation;
6+
using ObjCRuntime;
7+
8+
using NUnit.Framework;
9+
10+
namespace MonoTouchFixtures.ObjCRuntime {
11+
12+
[TestFixture]
13+
[Preserve (AllMembers = true)]
14+
public class NativeRuntimeTest {
15+
// bool xamarin_collapse_struct_name (const char *type, char struct_name[], int max_char, GCHandle *exception_gchandle)
16+
[DllImport ("__Internal")]
17+
unsafe static extern byte xamarin_collapse_struct_name (string type, StringBuilder struct_name, int max_char, ref IntPtr exception_gchandle);
18+
19+
[Test]
20+
public void XamarinCollapseStructName ()
21+
{
22+
AssertCollapsed ("{MKCoordinateRegion={CLLocationCoordinate2D=dd}{MKCoordinateSpan=dd}}", "dddd", "1");
23+
AssertCollapsed ("{CGRect=dddd}", "dddd", "2");
24+
AssertCollapsed ("^q", "^", "3");
25+
AssertCollapsed ("@?", "@", "4");
26+
AssertCollapsed ("^{CGRect={CGPoint=dd}{CGSize=dd}}", "^", "5");
27+
}
28+
29+
void AssertCollapsed (string input, string expected, string message)
30+
{
31+
var sb = new StringBuilder (255);
32+
var exception_gchandle = IntPtr.Zero;
33+
var rv = xamarin_collapse_struct_name (input, sb, sb.Length - 1, ref exception_gchandle);
34+
Assert.That (rv, Is.Not.EqualTo (0), $"rv/{message}");
35+
Assert.That (exception_gchandle, Is.EqualTo (IntPtr.Zero), $"exc/{message}");
36+
Assert.That (sb.ToString (), Is.EqualTo (expected), $"actual/{message}");
37+
}
38+
}
39+
}

tests/monotouch-test/ObjCRuntime/RegistrarTest.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4982,6 +4982,21 @@ public void MethodEncodings ()
49824982
}
49834983
}
49844984

4985+
[Test]
4986+
public void MethodEncodings2 ()
4987+
{
4988+
using (var met = new MethodEncodingsTests ()) {
4989+
nint obj1 = 1;
4990+
nint obj2 = 2;
4991+
nint obj3 = 3;
4992+
nint obj4 = 4;
4993+
CGRect obj5 = new CGRect (1, 2, 3, 4);
4994+
nint obj6 = 6;
4995+
Messaging.void_objc_msgSend_IntPtr_IntPtr_IntPtr_IntPtr_CGRect_IntPtr (met.Handle, Selector.GetHandle ("setPtrPropertyCGRect:p2:p3:p4:p5:p6:"), obj1, obj2, obj3, obj4, ref obj5, obj6);
4996+
Assert.AreEqual (new CGRect (5, 6, 7, 8), obj5, "rv");
4997+
}
4998+
}
4999+
49855000
class MethodEncodingsTests : NSObject, IObjCProtocolTest {
49865001
[Export ("methodEncodings:obj2:obj3:obj4:obj5:obj6:obj7:")]
49875002
public void GetMethodEncodings (ref NSObject obj1, ref NSObject obj2, ref NSObject obj3, ref NSObject obj4, ref NSObject obj5, ref NSObject obj6, ref NSObject obj7)
@@ -5001,6 +5016,19 @@ public void GetMethodEncodings (ref NSObject obj1, ref NSObject obj2, ref NSObje
50015016
obj6 = new NSObject ();
50025017
obj7 = new NSObject ();
50035018
}
5019+
5020+
[Export ("setPtrPropertyCGRect:p2:p3:p4:p5:p6:")]
5021+
void SetPtrPropertyCGRect (nint p1, nint p2, nint p3, nint p4, ref global::CoreGraphics.CGRect p5, nint p6)
5022+
{
5023+
Assert.AreEqual ((nint) 1, p1, "1");
5024+
Assert.AreEqual ((nint) 2, p2, "2");
5025+
Assert.AreEqual ((nint) 3, p3, "3");
5026+
Assert.AreEqual ((nint) 4, p4, "4");
5027+
Assert.AreEqual (new CGRect (1, 2, 3, 4), p5, "5a");
5028+
Assert.AreEqual ((nint) 6, p6, "6");
5029+
5030+
p5 = new CGRect (5, 6, 7, 8);
5031+
}
50045032
}
50055033

50065034
class RefOutParametersSubclass : BI1064.RefOutParameters {

tests/test-libraries/libtest.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ typedef unsigned int (^RegistrarTestBlock) (unsigned int magic);
197197
obj6: (byref NSObject **) obj6P
198198
obj7: (oneway NSObject **) obj7P
199199
;
200+
201+
-(void) setPtrPropertyCGRect: (void *) p1 p2:(void *)p2 p3:(void *)p3 p4:(void *)p4 p5:(CGRect*)p5 p6:(void *)p6;
200202
@end
201203

202204
// We need this class so that the ObjCProtocolTest protocol

0 commit comments

Comments
 (0)