Fix AV in System.StubHelpers.CSTRMarshaler.ConvertFixedToNative (#202)
authorFadi Hanna <fadim@microsoft.com>
Sat, 23 Nov 2019 05:43:36 +0000 (21:43 -0800)
committerGitHub <noreply@github.com>
Sat, 23 Nov 2019 05:43:36 +0000 (21:43 -0800)
* Fix AV in System.StubHelpers.CSTRMarshaler.ConvertFixedToNative

* Add test coverage

src/coreclr/src/System.Private.CoreLib/src/System/StubHelpers.cs
src/coreclr/tests/src/Interop/StructMarshalling/PInvoke/Helper.cs
src/coreclr/tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsLayoutSeq.cs
src/coreclr/tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h
src/coreclr/tests/src/Interop/StructMarshalling/PInvoke/Struct.cs

index 313798d..962254c 100644 (file)
@@ -125,6 +125,13 @@ namespace System.StubHelpers
 
         internal static unsafe void ConvertFixedToNative(int flags, string strManaged, IntPtr pNativeBuffer, int length)
         {
+            if (strManaged == null)
+            {
+                if (length > 0)
+                    *(byte*)pNativeBuffer = 0;
+                return;
+            }
+
             int numChars = strManaged.Length;
             if (numChars >= length)
             {
index 32c2106..c8eaaea 100644 (file)
@@ -590,10 +590,11 @@ public class Helper
     #endregion
     
     #region methods for S8 struct
-    public static S8 NewS8(string name, bool gender, UInt16 jobNum, int i32, uint ui32, sbyte mySByte)
+    public static S8 NewS8(string name, string fullName, bool gender, UInt16 jobNum, int i32, uint ui32, sbyte mySByte)
     {
         S8 s8 = new S8();
         s8.name = name;
+        s8.fullName = fullName;
         s8.gender = gender;
         s8.i32 = i32;
         s8.ui32 = ui32;
@@ -604,6 +605,7 @@ public class Helper
     public static void PrintS8(S8 str1, string name)
     {
         Console.WriteLine("\t{0}.name = {1}", name, str1.name);
+        Console.WriteLine("\t{0}.fullName = {1}", name, str1.fullName);
         Console.WriteLine("\t{0}.gender = {1}", name, str1.gender);
         Console.WriteLine("\t{0}.jobNum = {1}", name, str1.jobNum);
         Console.WriteLine("\t{0}.i32 = {1}", name, str1.i32);
@@ -612,7 +614,7 @@ public class Helper
     }
     public static bool ValidateS8(S8 str1, S8 str2, string methodName)
     {
-        if (str1.name != str2.name || str1.gender != str2.gender ||
+        if (str1.name != str2.name || str1.fullName != str2.fullName || str1.gender != str2.gender ||
             str1.jobNum != str2.jobNum ||
             str1.i32 != str2.i32 || str1.ui32 != str2.ui32 || str1.mySByte != str2.mySByte)
         {
index 696d1fe..c917b0a 100644 (file)
@@ -502,8 +502,8 @@ public class Managed
                     }
                     break;    
                 case StructID.S8Id:
-                    S8 sourceS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
-                    S8 cloneS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
+                    S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
+                    S8 cloneS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
 
                     Console.WriteLine("\tCalling MarshalStructAsParam_AsSeqByVal11...");
                     if (!MarshalStructAsParam_AsSeqByVal11(sourceS8))
@@ -904,8 +904,8 @@ public class Managed
                     }
                     break;    
                 case StructID.S8Id:
-                    S8 sourceS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
-                    S8 changeS8 = Helper.NewS8("world", false, 1, 256, 256, 64);
+                    S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
+                    S8 changeS8 = Helper.NewS8("world", "HelloWorldAgain", false, 1, 256, 256, 64);
 
                     Console.WriteLine("\tCalling MarshalStructAsParam_AsSeqByRef11...");
                     if (!MarshalStructAsParam_AsSeqByRef11(ref sourceS8))
@@ -1129,8 +1129,8 @@ public class Managed
                     }
                     break;    
                 case StructID.S8Id:
-                    S8 sourceS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
-                    S8 cloneS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
+                    S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
+                    S8 cloneS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
 
                     Console.WriteLine("\tCalling MarshalStructAsParam_AsSeqByValIn11...");
                     if (!MarshalStructAsParam_AsSeqByValIn11(sourceS8))
@@ -1355,8 +1355,8 @@ public class Managed
                     }
                     break;    
                 case StructID.S8Id:
-                    S8 sourceS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
-                    S8 cloneS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
+                    S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
+                    S8 cloneS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
 
                     Console.WriteLine("\tCalling MarshalStructAsParam_AsSeqByRefIn11...");
                     if (!MarshalStructAsParam_AsSeqByRefIn11(ref sourceS8))
@@ -1580,8 +1580,8 @@ public class Managed
                     }
                     break;    
                 case StructID.S8Id:
-                    S8 sourceS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
-                    S8 cloneS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
+                    S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
+                    S8 cloneS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
 
                     Console.WriteLine("\tCalling MarshalStructAsParam_AsSeqByValOut11...");
                     if (!MarshalStructAsParam_AsSeqByValOut11(sourceS8))
@@ -1806,8 +1806,8 @@ public class Managed
                     }
                     break;    
                 case StructID.S8Id:
-                    S8 sourceS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
-                    S8 changeS8 = Helper.NewS8("world", false, 1, 256, 256, 64);
+                    S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
+                    S8 changeS8 = Helper.NewS8("world", "HelloWorldAgain", false, 1, 256, 256, 64);
 
                     Console.WriteLine("\tCalling MarshalStructAsParam_AsSeqByRefOut11...");
                     if (!MarshalStructAsParam_AsSeqByRefOut11(out sourceS8))
@@ -2035,8 +2035,8 @@ public class Managed
                     }
                     break;    
                 case StructID.S8Id:
-                    S8 sourceS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
-                    S8 cloneS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
+                    S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
+                    S8 cloneS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
 
                     Console.WriteLine("\tCalling MarshalStructAsParam_AsSeqByValInOut11...");
                     if (!MarshalStructAsParam_AsSeqByValInOut11(sourceS8))
@@ -2261,8 +2261,8 @@ public class Managed
                     }
                     break;    
                 case StructID.S8Id:
-                    S8 sourceS8 = Helper.NewS8("hello", true, 10, 128, 128, 32);
-                    S8 changeS8 = Helper.NewS8("world", false, 1, 256, 256, 64);
+                    S8 sourceS8 = Helper.NewS8("hello", null, true, 10, 128, 128, 32);
+                    S8 changeS8 = Helper.NewS8("world", "HelloWorldAgain", false, 1, 256, 256, 64);
 
                     Console.WriteLine("\tCalling MarshalStructAsParam_AsSeqByRefInOut11...");
                     if (!MarshalStructAsParam_AsSeqByRefInOut11(ref sourceS8))
@@ -2558,4 +2558,4 @@ public class Managed
 }
 
 
-   
\ No newline at end of file
+   
index 5429dcf..abf47cf 100644 (file)
@@ -589,6 +589,7 @@ void ChangeStringStructSequentialUnicode(StringStructSequentialUnicode* str)
 struct S8
 {
     LPCSTR name;
+    CHAR fullName[128];
     BOOL gender;
     INT i32;
     UINT ui32;
@@ -598,6 +599,7 @@ struct S8
 void PrintS8(S8* str, char const * name)
 {
        printf("\t%s.name = %s\n",name, str->name);
+       printf("\t%s.fullName = %s\n", name, str->fullName);
        printf("\t%s.gender = %d\n", name, str->gender);
        printf("\t%s.jobNum = %d\n",name, str->jobNum);
        printf("\t%s.i32 = %d\n", name, str->i32);
@@ -608,6 +610,8 @@ bool IsCorrectS8(S8* str)
 {
        if(memcmp( str->name,"hello", strlen("hello")*sizeof(char)+1 )!= 0)
                return false;
+       if (str->fullName[0] != 0)
+               return false;
        if(!str->gender)
                return false;
        if(str->jobNum != 10)
@@ -622,6 +626,7 @@ bool IsCorrectS8(S8* str)
 void ChangeS8(S8* str)
 {
        str->name = CoStrDup("world");
+       sprintf_s(str->fullName, 128, "HelloWorldAgain");
        str->gender = false;
        str->jobNum = 1;
        str->i32 = 256;
index db598b8..750548a 100644 (file)
@@ -190,6 +190,8 @@ public struct StringStructSequentialUnicode
 public struct S8
 {
     public string name;
+    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
+    public string fullName;
     public bool gender;
     [MarshalAs(UnmanagedType.Error)]
     public int i32;