Check for null and valuetypes.
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 30 Nov 2010 16:52:41 +0000 (14:52 -0200)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 30 Nov 2010 16:54:27 +0000 (14:54 -0200)
* CustomAttributeBuilder.cs (Initialize): Check if we are
not passing null as values to valuetypes as this is invalid.

Fixes #515938

mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs
mcs/class/corlib/Test/System.Reflection.Emit/CustomAttributeBuilderTest.cs

index 06492edf31c36bc2d098cb78ce03c87920689e48..b1f7a490ed497070dc8053760ceb3916b9e46eeb 100644 (file)
@@ -117,6 +117,18 @@ namespace System.Reflection.Emit {
                        return true;
                }
 
+               static bool IsValidValue (Type type, object value) {
+                       if (type.IsValueType && value == null)
+                               return false;
+                       if (type.IsArray && type.GetElementType ().IsValueType) {
+                               foreach (var v in (Array)value) {
+                                       if (v == null)
+                                               return false;
+                               }
+                       }
+                       return true;
+               } 
+
                private void Initialize (ConstructorInfo con, object [] constructorArgs,
                                PropertyInfo [] namedProperties, object [] propertyValues,
                                FieldInfo [] namedFields, object [] fieldValues)
@@ -156,6 +168,8 @@ namespace System.Reflection.Emit {
                                        throw new ArgumentException ("Field '" + fi.Name + "' does not belong to the same class as the constructor");
                                if (!IsValidType (fi.FieldType))
                                        throw new ArgumentException ("Field '" + fi.Name + "' does not have a valid type.");
+                               if (!IsValidValue (fi.FieldType, fieldValues [i]))
+                                       throw new ArgumentException ("Field " + fi.Name + " is not a valid value.");
                                // FIXME: Check enums and TypeBuilders as well
                                if (fieldValues [i] != null)
                                        // IsEnum does not seem to work on TypeBuilders
@@ -179,6 +193,8 @@ namespace System.Reflection.Emit {
                                        throw new ArgumentException ("Property '" + pi.Name + "' does not belong to the same class as the constructor");
                                if (!IsValidType (pi.PropertyType))
                                        throw new ArgumentException ("Property '" + pi.Name + "' does not have a valid type.");
+                               if (!IsValidValue (pi.PropertyType, propertyValues [i]))
+                                       throw new ArgumentException ("Property " + pi.Name + " is not a valid value.");
                                if (propertyValues [i] != null) {
                                        if (!(pi.PropertyType is TypeBuilder) && !pi.PropertyType.IsEnum && !pi.PropertyType.IsInstanceOfType (propertyValues [i]))
                                                if (!pi.PropertyType.IsArray)
@@ -193,12 +209,15 @@ namespace System.Reflection.Emit {
                                        Type paramType = pi.ParameterType;
                                        if (!IsValidType (paramType))
                                                throw new ArgumentException ("Parameter " + i + " does not have a valid type.");
+                                       if (!IsValidValue (paramType, constructorArgs [i]))
+                                               throw new ArgumentException ("Parameter " + i + " is not a valid value.");
+                                       
                                        if (constructorArgs [i] != null) {
                                                if (!(paramType is TypeBuilder) && !paramType.IsEnum && !paramType.IsInstanceOfType (constructorArgs [i]))
                                                        if (!paramType.IsArray)
                                                                throw new ArgumentException ("Value of argument " + i + " does not match parameter type: " + paramType + " -> " + constructorArgs [i]);
                                                if (!IsValidParam (constructorArgs [i], paramType))
-                                                       throw new ArgumentException ("Cannot emit a CustomAttribute with argument of type " + constructorArgs [i].GetType () + ".");
+                                                       throw new ArgumentException ("Cannot emit a CustomAttribute with argument of type " + constructorArgs [i].GetType () + "."); 
                                        }
                                }
                                i ++;
index 175e0bdc3b562d4fec9832135da5a011a5ace3f0..c104f4eb8eedb787627d74dce701d8af5326196b 100644 (file)
@@ -645,6 +645,39 @@ namespace MonoTests.System.Reflection.Emit
                                                 typeof (C).GetConstructors ()[0],
                                                 new object[] { new C (1) });
                }
+
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void ValueTypeParam_Null ()
+               {
+               ConstructorInfo classCtorInfo = 
+                   typeof (CattrD).GetConstructors ()[0];
+       
+               CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
+                   classCtorInfo, new object [] { null });
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void ValueTypeArrayParam_Null ()
+               {
+               ConstructorInfo classCtorInfo = 
+                   typeof (CattrE).GetConstructors ()[0];
+       
+               CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
+                   classCtorInfo, new object [] { new object[] { null } });
+               }
+               
+               public class CattrD : Attribute
+               {
+                   public CattrD (bool b) {}
+               }
+               
+               public class CattrE : Attribute
+               {
+                   public CattrE (bool[] b) {}
+               }
        }
 }