Fix marshalling UTF8 string struct member from native to managed. (dotnet/coreclr...
authorJeremy Koritzinsky <jkoritzinsky@gmail.com>
Tue, 5 Feb 2019 06:16:43 +0000 (22:16 -0800)
committerGitHub <noreply@github.com>
Tue, 5 Feb 2019 06:16:43 +0000 (22:16 -0800)
* Fix marshalling UTF8 string struct member from native to managed.

Fixes dotnet/coreclr#22394

* PR Feedback.

Commit migrated from https://github.com/dotnet/coreclr/commit/b52d64f04f61889c4bb0eb4cd9a39d6899eace09

src/coreclr/src/vm/fieldmarshaler.cpp
src/coreclr/tests/src/Interop/StringMarshalling/UTF8/UTF8Test.cs
src/coreclr/tests/src/Interop/StringMarshalling/UTF8/UTF8TestNative.cpp

index 5c6a7db..e0b3a4a 100644 (file)
@@ -3291,16 +3291,12 @@ VOID FieldMarshaler_StringUtf8::UpdateCLRImpl(const VOID *pNativeValue, OBJECTRE
 
     STRINGREF pString = NULL;
     LPCUTF8  sz = (LPCUTF8)MAYBE_UNALIGNED_READ(pNativeValue, _PTR);
-    if (!sz)
-    {
-        pString = NULL;
-    }
-    else
+    if (sz)
     {
         MethodDescCallSite convertToManaged(METHOD__CUTF8MARSHALER__CONVERT_TO_MANAGED);
         ARG_SLOT args[] =
         {
-            PtrToArgSlot(pNativeValue),
+            PtrToArgSlot(sz),
         };
         pString = convertToManaged.Call_RetSTRINGREF(args);
     }
index 2e9e685..2dd8dee 100644 (file)
@@ -141,6 +141,9 @@ class UTF8StructMarshalling
     [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)]
     public static extern void TestStructWithUtf8Field(Utf8Struct utfStruct);
 
+    [DllImport("UTF8TestNative", CallingConvention = CallingConvention.Cdecl)]
+    public static extern void SetStringInStruct(ref Utf8Struct utfStruct, [MarshalAs(UnmanagedType.LPUTF8Str)] string str);
+
     public static void TestUTF8StructMarshalling(string[] utf8Strings)
     {
         Utf8Struct utf8Struct = new Utf8Struct();
@@ -152,6 +155,15 @@ class UTF8StructMarshalling
         }
         if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
          CompareWithUTF8Encoding();
+
+        string testString = "StructTestString\uD83D\uDE00";
+
+        SetStringInStruct(ref utf8Struct, testString);
+
+        if (utf8Struct.FirstName != testString)
+        {
+            throw new Exception("Incorrect UTF8 string marshalled back from native to managed.");
+        }
    }
    
    unsafe static void CompareWithUTF8Encoding()
index e623d2d..9c720ad 100644 (file)
@@ -234,6 +234,16 @@ extern "C" DLL_EXPORT void __cdecl TestStructWithUtf8Field(struct FieldWithUtf8
     free_utf8_string(pszNative);
 }
 
+extern "C" DLL_EXPORT void __cdecl SetStringInStruct(FieldWithUtf8* fieldStruct, char* str)
+{
+    size_t strLength = strlen(str);
+    char* strCopy = (char*)CoreClrAlloc(sizeof(char) * strlen(str) + 1);
+
+    memcpy(strCopy, str, strLength + 1);
+    fieldStruct->pFirst = strCopy;
+    fieldStruct->index = 0;
+}
+
 // test c# out keyword
 extern "C" DLL_EXPORT void __cdecl StringParameterRefOut(/*out*/ char **s, int index)
 {