Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mcs
diff options
context:
space:
mode:
authorSteve Pfister <steveisok@users.noreply.github.com>2020-03-03 23:26:46 +0300
committerGitHub <noreply@github.com>2020-03-03 23:26:46 +0300
commitc483eaf070b9eeb147e6d396d23639f0d370d09e (patch)
tree939b5f34a256897537c602b21a5ebb12ba275857 /mcs
parentede05b997bf7a98ebd712a5c6731c5ad2b9153b4 (diff)
Changed Max and MinLengthAttribute validation (#19084)
It should now validate against ICollection or any other type that has a Count property for that matter. We're still relying on the reference source implementation because corefx strips some types out. Fixes https://github.com/mono/mono/issues/19022
Diffstat (limited to 'mcs')
-rw-r--r--mcs/class/System.ComponentModel.DataAnnotations/ReferenceSources/SR.cs1
-rw-r--r--mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.csproj1
-rw-r--r--mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.dll.sources1
-rw-r--r--mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations_test.dll.sources1
-rw-r--r--mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/MaxMinLengthAttributeTest.cs77
-rw-r--r--mcs/class/System.ComponentModel.DataAnnotations/corefx/CountPropertyHelper.cs27
-rw-r--r--mcs/class/referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/MaxLengthAttribute.cs16
-rw-r--r--mcs/class/referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/MinLengthAttribute.cs17
8 files changed, 125 insertions, 16 deletions
diff --git a/mcs/class/System.ComponentModel.DataAnnotations/ReferenceSources/SR.cs b/mcs/class/System.ComponentModel.DataAnnotations/ReferenceSources/SR.cs
index 35ee14f949f..5cda102a1cd 100644
--- a/mcs/class/System.ComponentModel.DataAnnotations/ReferenceSources/SR.cs
+++ b/mcs/class/System.ComponentModel.DataAnnotations/ReferenceSources/SR.cs
@@ -63,5 +63,6 @@ partial class DataAnnotationsResources
public const string MinLengthAttribute_InvalidMinLength = "MinLengthAttribute must have a Length value that is zero or greater.";
public const string MinLengthAttribute_ValidationError = "The field {0} must be a string or array type with a minimum length of '{1}'.";
public const string ArgumentIsNullOrWhitespace = "The argument '{0}' cannot be null, empty or contain only white space.";
+ public const string LengthAttribute_InvalidValueType = "The field of type {0} must be a string, array or ICollection type.";
}
} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.csproj b/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.csproj
index 8257ab78c78..4998156ab08 100644
--- a/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.csproj
+++ b/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.csproj
@@ -168,6 +168,7 @@
<Compile Include="..\referencesource\System.ComponentModel.DataAnnotations\DataAnnotations\Validator.cs" />
<Compile Include="Assembly\AssemblyInfo.cs" />
<Compile Include="ReferenceSources\SR.cs" />
+ <Compile Include="corefx\CountPropertyHelper.cs" />
<ProjectReference Include="$(SolutionDir)\msvc\scripts\genconsts.csproj">
<Name>genconsts</Name>
<Project>{702AE2C0-71DD-4112-9A06-E4FABCA59986}</Project>
diff --git a/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.dll.sources b/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.dll.sources
index c41ac4477fe..fc1acff6a10 100644
--- a/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.dll.sources
+++ b/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.dll.sources
@@ -1,5 +1,6 @@
../../build/common/Consts.cs
Assembly/AssemblyInfo.cs
+corefx/CountPropertyHelper.cs
../referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/AppSettings.cs
../referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/AssociatedMetadataTypeTypeDescriptionProvider.cs
../referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/AssociatedMetadataTypeTypeDescriptor.cs
diff --git a/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations_test.dll.sources b/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations_test.dll.sources
index 9454422b250..663f8288e4c 100644
--- a/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations_test.dll.sources
+++ b/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations_test.dll.sources
@@ -18,3 +18,4 @@ System.ComponentModel.DataAnnotations/PhoneAttributeTest.cs
System.ComponentModel.DataAnnotations/CreditCardAttributeTest.cs
System.ComponentModel.DataAnnotations/FileExtensionsAttributeTest.cs
System.ComponentModel.DataAnnotations/CompareAttributeTest.cs
+System.ComponentModel.DataAnnotations/MaxMinLengthAttributeTest.cs
diff --git a/mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/MaxMinLengthAttributeTest.cs b/mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/MaxMinLengthAttributeTest.cs
new file mode 100644
index 00000000000..e664f068273
--- /dev/null
+++ b/mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/MaxMinLengthAttributeTest.cs
@@ -0,0 +1,77 @@
+//
+// MaxMinLengthAttributeTest.cs
+//
+// Copyright (C) 2010 Novell, Inc. (http://novell.com/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+using NUnit.Framework;
+
+namespace MonoTests.System.ComponentModel.DataAnnotations
+{
+ [TestFixture]
+ public class MaxMinLengthAttributeTest
+ {
+ [Test]
+ public void CheckMinLength () {
+ var attr = new MinLengthAttribute (2);
+
+ Assert.IsTrue (attr.IsValid (null), "#A1");
+ Assert.IsFalse (attr.IsValid ("1"), "#A2");
+
+ Assert.IsTrue (attr.IsValid ("12"), "#A3");
+ Assert.IsTrue (attr.IsValid ("123"), "#A4");
+
+ Assert.IsFalse (attr.IsValid (BuildQuickList (1)), "#A5");
+ Assert.IsTrue (attr.IsValid (BuildQuickList (2)), "#A6");
+ Assert.IsTrue (attr.IsValid (BuildQuickList (3)), "#A7");
+ }
+
+ [Test]
+ public void CheckMaxLength () {
+ var attr = new MaxLengthAttribute (2);
+
+ Assert.IsTrue (attr.IsValid (null), "#A1");
+ Assert.IsTrue (attr.IsValid ("1"), "#A2");
+ Assert.IsTrue (attr.IsValid ("12"), "#A3");
+
+ Assert.IsFalse (attr.IsValid ("123"), "#A4");
+
+ Assert.IsTrue (attr.IsValid (BuildQuickList (1)), "#A5");
+ Assert.IsTrue (attr.IsValid (BuildQuickList (2)), "#A6");
+ Assert.IsFalse (attr.IsValid (BuildQuickList (3)), "#A7");
+ }
+
+ List<string> BuildQuickList (int count) {
+ var items = new List<string> ();
+
+ for (int i = 0; i < count; i++) {
+ items.Add(i.ToString());
+ }
+
+ return items;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.DataAnnotations/corefx/CountPropertyHelper.cs b/mcs/class/System.ComponentModel.DataAnnotations/corefx/CountPropertyHelper.cs
new file mode 100644
index 00000000000..f91a97ee27f
--- /dev/null
+++ b/mcs/class/System.ComponentModel.DataAnnotations/corefx/CountPropertyHelper.cs
@@ -0,0 +1,27 @@
+using System.Collections;
+using System.Diagnostics;
+using System.Reflection;
+
+internal static class CountPropertyHelper
+{
+ public static bool TryGetCount(object value, out int count)
+ {
+ Debug.Assert(value != null);
+
+ if (value is ICollection collection)
+ {
+ count = collection.Count;
+ return true;
+ }
+
+ PropertyInfo property = value.GetType().GetRuntimeProperty("Count");
+ if (property != null && property.CanRead && property.PropertyType == typeof(int))
+ {
+ count = (int)property.GetValue(value);
+ return true;
+ }
+
+ count = -1;
+ return false;
+ }
+} \ No newline at end of file
diff --git a/mcs/class/referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/MaxLengthAttribute.cs b/mcs/class/referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/MaxLengthAttribute.cs
index 8c983c737e4..6d3e61611a0 100644
--- a/mcs/class/referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/MaxLengthAttribute.cs
+++ b/mcs/class/referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/MaxLengthAttribute.cs
@@ -60,15 +60,15 @@ namespace System.ComponentModel.DataAnnotations {
if (value == null) {
return true;
}
+
+ if (value is string str) {
+ length = str.Length;
+ }
+ else if (CountPropertyHelper.TryGetCount(value, out var count)) {
+ length = count;
+ }
else {
- var str = value as string;
- if (str != null) {
- length = str.Length;
- }
- else {
- // We expect a cast exception if a non-{string|array} property was passed in.
- length = ((Array)value).Length;
- }
+ throw new InvalidCastException(String.Format(DataAnnotationsResources.LengthAttribute_InvalidValueType, value.GetType()));
}
return MaxAllowableLength == Length || length <= Length;
diff --git a/mcs/class/referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/MinLengthAttribute.cs b/mcs/class/referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/MinLengthAttribute.cs
index ca80e8e1e44..1b1204b67a6 100644
--- a/mcs/class/referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/MinLengthAttribute.cs
+++ b/mcs/class/referencesource/System.ComponentModel.DataAnnotations/DataAnnotations/MinLengthAttribute.cs
@@ -45,15 +45,16 @@ namespace System.ComponentModel.DataAnnotations {
if (value == null) {
return true;
}
+
+ if (value is string str) {
+ length = str.Length;
+ }
+ else if (CountPropertyHelper.TryGetCount(value, out var count))
+ {
+ length = count;
+ }
else {
- var str = value as string;
- if (str != null) {
- length = str.Length;
- }
- else {
- // We expect a cast exception if a non-{string|array} property was passed in.
- length = ((Array)value).Length;
- }
+ throw new InvalidCastException(String.Format(DataAnnotationsResources.LengthAttribute_InvalidValueType, value.GetType()));
}
return length >= Length;