Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Respect the SizeConst parameter to UnmanagedType.ByValTStr. Fixes #2567.

  • Loading branch information...
commit aa3a6e8f42bbe78f7d787a28a605cb49220049f3 1 parent 3c91695
@vargaz vargaz authored
Showing with 64 additions and 7 deletions.
  1. +28 −3 mono/metadata/marshal.c
  2. +36 −4 mono/tests/marshal2.cs
View
31 mono/metadata/marshal.c
@@ -113,6 +113,9 @@ mono_string_utf16_to_builder2 (gunichar2 *text);
static MonoString*
mono_string_new_len_wrapper (const char *text, guint length);
+static MonoString *
+mono_string_from_byvalwstr (gunichar2 *data, int len);
+
static void
mono_byvalarray_to_array (MonoArray *arr, gpointer native_arr, MonoClass *eltype, guint32 elnum);
@@ -212,6 +215,7 @@ mono_marshal_init (void)
register_icall (mono_marshal_string_to_utf16_copy, "mono_marshal_string_to_utf16_copy", "ptr obj", FALSE);
register_icall (mono_string_to_utf16, "mono_string_to_utf16", "ptr obj", FALSE);
register_icall (mono_string_from_utf16, "mono_string_from_utf16", "obj ptr", FALSE);
+ register_icall (mono_string_from_byvalwstr, "mono_string_from_byvalwstr", "obj ptr int", FALSE);
register_icall (mono_string_new_wrapper, "mono_string_new_wrapper", "obj ptr", FALSE);
register_icall (mono_string_new_len_wrapper, "mono_string_new_len_wrapper", "obj ptr int", FALSE);
register_icall (mono_string_to_utf8, "mono_string_to_utf8", "ptr obj", FALSE);
@@ -529,6 +533,20 @@ mono_delegate_free_ftnptr (MonoDelegate *delegate)
}
}
+static MonoString *
+mono_string_from_byvalwstr (gunichar2 *data, int max_len)
+{
+ MonoDomain *domain = mono_domain_get ();
+ int len = 0;
+
+ if (!data)
+ return NULL;
+
+ while (data [len]) len++;
+
+ return mono_string_new_utf16 (domain, data, MIN (len, max_len));
+}
+
gpointer
mono_array_to_savearray (MonoArray *array)
{
@@ -1304,9 +1322,16 @@ emit_ptr_to_object_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv
mono_mb_emit_byte (mb, CEE_STIND_REF);
break;
case MONO_MARSHAL_CONV_STR_BYVALWSTR:
- mono_mb_emit_ldloc (mb, 1);
- mono_mb_emit_ldloc (mb, 0);
- mono_mb_emit_icall (mb, mono_string_from_utf16);
+ if (mspec && mspec->native == MONO_NATIVE_BYVALTSTR && mspec->data.array_data.num_elem) {
+ mono_mb_emit_ldloc (mb, 1);
+ mono_mb_emit_ldloc (mb, 0);
+ mono_mb_emit_icon (mb, mspec->data.array_data.num_elem);
+ mono_mb_emit_icall (mb, mono_string_from_byvalwstr);
+ } else {
+ mono_mb_emit_ldloc (mb, 1);
+ mono_mb_emit_ldloc (mb, 0);
+ mono_mb_emit_icall (mb, mono_string_from_utf16);
+ }
mono_mb_emit_byte (mb, CEE_STIND_REF);
break;
case MONO_MARSHAL_CONV_STR_LPTSTR:
View
40 mono/tests/marshal2.cs
@@ -5,7 +5,7 @@
using System;
using System.Runtime.InteropServices;
-public class Test {
+public class Tests {
[StructLayout (LayoutKind.Sequential)]
@@ -43,7 +43,13 @@ public struct ByValWStrStruct {
public int i;
}
- public unsafe static int Main () {
+ public unsafe static int Main (String[] args) {
+ if (TestDriver.RunTests (typeof (Tests), args) != 0)
+ return 34;
+ return 0;
+ }
+
+ public static int test_0_structure_to_ptr () {
SimpleStruct ss = new SimpleStruct ();
int size = Marshal.SizeOf (typeof (SimpleStruct));
@@ -153,8 +159,21 @@ public struct ByValWStrStruct {
if (cp.a2 [1] != 'b')
return 30;
+ return 0;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
+ public struct Struct1
+ {
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
+ public string Field1;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
+ public string Field2;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
+ public string Field3;
+ }
- /* ByValTStr with Unicode */
+ public static int test_0_byvaltstr_unicode () {
ByValWStrStruct s = new ByValWStrStruct ();
IntPtr p2 = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (ByValWStrStruct)));
@@ -178,8 +197,21 @@ public struct ByValWStrStruct {
if (s2.i != 55)
return 33;
+ return 0;
+ }
+
+ public static int test_0_byvaltstr_max_size () {
+ string buffer = "12345678123456789012345678901234";
+ IntPtr ptr = Marshal.StringToBSTR (buffer);
+
+ Struct1 data = (Struct1)Marshal.PtrToStructure (ptr, typeof (Struct1));
+ if (data.Field1 != "12345678")
+ return 1;
+ if (data.Field2 != "1234567890")
+ return 2;
+ if (data.Field3 != "12345678901234")
+ return 3;
return 0;
}
}
-
Please sign in to comment.
Something went wrong with that request. Please try again.