From 9e9543bb382ffa5d8ddd3581fd851259e07f3fa6 Mon Sep 17 00:00:00 2001 From: mrj001 <62225294+mrj001@users.noreply.github.com> Date: Fri, 17 Apr 2020 21:55:36 -0600 Subject: [PATCH] Remove erroneous curlies in Xml resource (#33890) * Added test for Issue 30218, use of resource Sch_MinLengthGtBaseMinLength * Reworded error message to remove the invalid formatters. Issue #30218 * Updated check of message from the exception to be more amenable to potential internationalization. * Reworded resource Sch_MaxLengthGtBaseMaxLength and added unit test for same. * Simplified test code per feedback from Dan Moseley, PR#33890. * Tests to increase code coverage. The ones that are failing trigger resource string Sch_MaxMinLengthBaseLength to be used as the Exception message. * Removed invalid formatters from the resource string Sch_MaxMinLengthBaseLength. Failing tests from the previous commit now pass. * Added test for the Exception using string resource Sch_LengthGtBaseLength as its message. This covers a source line and branch not previously covered. This test fails due to the invalid formatters. * Reworded string resource Sch_LengthGtBaseLength to remove the invalid formatters. * Added unit tests for uses of string resource Sch_FacetBaseFixed. * Made test for the message containing "fixed" more specific. * Reworded string resource Sch_FacetBaseFixed to remove the invalid formatter. * Added unit test to cover usage of string resource Sch_InvalidAllMax. A second usage of this string resource is not covered as it is in a class marked Obsolete. * Reworded string resource Sch_InvalidAllMax to remove the invalid formatter. * Added unit test for String Resource Sch_InvalidAllElementMax - invalid formatter. * Reworded string resource Sch_InvalidAllElementMax to remove the invalid formatter. * Added unit test which causes an XmlSchemaException using string resource Sch_InvalidExemplar as its message. * Reworded Sch_InvalidExemplar to remove the invalid formatter. Also, added the name of the element which cannot be used as the substitution group affiliation. * Added unit test that causes an XmlSchemaException to be thrown using string resource Sch_GroupBaseRestNotEmptiable as its message. * Removed the curly braces so there are no longer any invalid formatters. * Added unit tests that cause an XmlSchemaException to be thrown using string resource Sch_AllRefMinMax as its message. * Changed string resource Sch_AllRefMinMax to remove the invalid formatters. * reworded Sch_MinLengthGtBaseMinLength and Sch_MaxLengthGtBaseMaxLength similarly to Sch_LengthGtBaseLength * Corrected error "greater than" to "less than". * Changed name of test to more accurately reflect its purpose. * Changed casing of MinLength and MaxLength to match their XML facets. Removed redundant ToLower call and comment. * Removed all Regex used to find invalid formatters. * renamed MaxMinLengthBaseLength_TestData to indicate that this is testing the successful case. * Removed suppression of exception so that we will see the exception if one is thrown. * Removed comments as there are issues tracking these. * Fixed comment larger -> lower. * Removed XML comments on test methods. * Removal of XML comment that was missed. --- .../src/Resources/Strings.resx | 24 +- .../Xml/Schema/SchemaCollectionCompiler.cs | 2 +- .../System/Xml/Schema/SchemaSetCompiler.cs | 2 +- .../XmlSchemaSet/TC_SchemaSet_Compile.cs | 916 ++++++++++++++++++ 4 files changed, 930 insertions(+), 14 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/Resources/Strings.resx b/src/libraries/System.Private.Xml/src/Resources/Strings.resx index e2042282f456ac..73ea65d48d8480 100644 --- a/src/libraries/System.Private.Xml/src/Resources/Strings.resx +++ b/src/libraries/System.Private.Xml/src/Resources/Strings.resx @@ -1120,7 +1120,7 @@ It is an error for both length and minLength or maxLength to be present. - MinLength is greater than MaxLength. + minLength is greater than maxLength. FractionDigits is greater than TotalDigits. @@ -1396,7 +1396,7 @@ 'all' must have 'minOccurs' value of 0 or 1. - 'all' must have {max occurs}=1. + 'all' must have a 'maxOccurs' value of 1. The 'value' attribute must be present in facet. @@ -1501,7 +1501,7 @@ Duplicate ID attribute. - The {max occurs} of all the particles in the {particles} of an all group must be 0 or 1. + The 'maxOccurs' attribute of all the particles of an 'all' group must be 0 or 1. Invalid namespace in 'any'. @@ -1510,7 +1510,7 @@ The value of the namespace attribute of the element or attribute wildcard is invalid - {0} - Cannot be nominated as the {substitution group affiliation} of any other declaration. + Element '{0}' cannot be nominated as the 'substitutionGroup' of any other declaration. Reference to undeclared substitution group affiliation. @@ -1636,7 +1636,7 @@ The derived particle cannot have more members than the base particle - All:All,Sequence:Sequence -- Recurse Rule 2 / Choice:Choice -- RecurseLax. - All particles in the {particles} of the base particle which are not mapped to by any particle in the {particles} of the derived particle should be emptiable - All:All,Sequence:Sequence -- Recurse Rule 2 / Choice:Choice -- RecurseLax. + All particles in the particles of the base particle which are not mapped to by any particle in the particles of the derived particle should be emptiable - All:All,Sequence:Sequence -- Recurse Rule 2 / Choice:Choice -- RecurseLax. The derived sequence particle at ({0}, {1}) is not a valid restriction of the base all particle at ({2}, {3}) according to Sequence:All -- RecurseUnordered. @@ -1654,7 +1654,7 @@ The group ref to 'all' is not the root particle, or it is being used as an extension. - The group ref to 'all' must have {min occurs}= 0 or 1 and {max occurs}=1. + The group ref to 'all' must have 'minOccurs' = 0 or 1 and 'maxOccurs' = 1. 'all' is not the only particle in a group, or is being used as an extension. @@ -1720,16 +1720,16 @@ Cannot load the schema from the location '{0}' - {1} - It is an error if 'length' is among the members of {facets} of {base type definition} and {value} is greater than the {value} of the parent 'length'. + It is an error if 'length' is among the members of the facets of the base type definition and its value is greater than the value of the parent 'length'. - It is an error if 'minLength' is among the members of {facets} of {base type definition} and {value} is less than the {value} of the parent 'minLength'. + It is an error if 'minLength' is among the members of the facets of the base type definition and its value is less than the value of the parent 'minLength'. - It is an error if 'maxLength' is among the members of {facets} of {base type definition} and {value} is greater than the {value} of the parent 'maxLength'. + It is an error if 'maxLength' is among the members of the facets of the base type definition and its value is greater than the value of the parent 'maxLength'. - It is an error for both 'length' and either 'minLength' or 'maxLength' to be members of {facets}, unless they are specified in different derivation steps. In which case the following must be true: the {value} of 'minLength' <= the {value} of 'length' <= the {value} of 'maxLength'. + It is an error for both 'length' and either 'minLength' or 'maxLength' to be members of facets, unless they are specified in different derivation steps. In which case the following must be true: the value of 'minLength' <= the value of 'length' <= the value of 'maxLength'. It is an error if the derived 'maxInclusive' facet value is greater than the parent 'maxInclusive' facet value. @@ -1768,7 +1768,7 @@ It is an error if the derived 'fractionDigits' facet value is greater than the parent 'fractionDigits' facet value. - Values that are declared as {fixed} in a base type can not be changed in a derived type. + Values that are declared with fixed='true' in a base type can not be changed in a derived type. It is an error if 'whiteSpace' is among the members of {facets} of {base type definition}, {value} is 'replace' or 'preserve', and the {value} of the parent 'whiteSpace' is 'collapse'. @@ -3456,4 +3456,4 @@ Usage: dotnet {0} [--assembly <assembly file path>] [--type <type name& Compiling JScript/CSharp scripts is not supported - + \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionCompiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionCompiler.cs index 079a6e20f13430..56766e67a3d9f6 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionCompiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionCompiler.cs @@ -437,7 +437,7 @@ private void CompileSubstitutionGroup(XmlSchemaSubstitutionGroupV1Compat substit { if (examplar.FinalResolved == XmlSchemaDerivationMethod.All) { - SendValidationEvent(SR.Sch_InvalidExamplar, examplar); + SendValidationEvent(SR.Sch_InvalidExamplar, examplar.Name, examplar); } for (int i = 0; i < substitutionGroup.Members.Count; ++i) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaSetCompiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaSetCompiler.cs index db6b8b075f6b31..3f794a9dc54908 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaSetCompiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaSetCompiler.cs @@ -487,7 +487,7 @@ private void CompileSubstitutionGroup(XmlSchemaSubstitutionGroup substitutionGro { if (examplar.FinalResolved == XmlSchemaDerivationMethod.All) { - SendValidationEvent(SR.Sch_InvalidExamplar, examplar); + SendValidationEvent(SR.Sch_InvalidExamplar, examplar.Name, examplar); } //Build transitive members ArrayList newMembers = null; diff --git a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Compile.cs b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Compile.cs index 80842b9b2d4ad8..122239cc26f041 100644 --- a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Compile.cs +++ b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Compile.cs @@ -6,6 +6,7 @@ using Xunit.Abstractions; using System.IO; using System.Xml.Schema; +using System.Collections.Generic; namespace System.Xml.Tests { @@ -176,5 +177,920 @@ public void FractionDigitsMismatch_Throws() Assert.Contains("fractionDigits", ex.Message); Assert.DoesNotContain("totalDigits", ex.Message); } + + [Fact] + public void MinLengthLtBaseMinLength_Throws() + { + string schema = @" + + + + + + + + + + + + +"; + + XmlSchemaSet ss = new XmlSchemaSet(); + ss.Add(null, XmlReader.Create(new StringReader(schema))); + + Exception ex = Assert.Throws(() => ss.Compile()); + Assert.Contains("minLength", ex.Message); + } + + [Fact] + public void MaxLengthGtBaseMaxLength_Throws() + { + string schema = @" + + + + + + + + + + + + +"; + + XmlSchemaSet ss = new XmlSchemaSet(); + ss.Add(null, XmlReader.Create(new StringReader(schema))); + + Exception ex = Assert.Throws(() => ss.Compile()); + Assert.Contains("maxLength", ex.Message); + } + + #region "Testing presence of minLength or maxLength and Length" + + public static IEnumerable MaxMinLengthBaseLength_ThrowsData + { + get + { + return new List() + { + new object[] + { // minLength and length specified in same derivation step. + @" + + + + + + + + +" + }, + new object[] + { // maxLength and length specified in same derivation step. + @" + + + + + + + + +" + }, + new object[] + { // base type has minLength; derived type has lesser length + @" + + + + + + + + + + + + +" + }, + new object[] + { // base type has maxLength; derived type has greater length + @" + + + + + + + + + + + + +" + }, + new object[] + { // base type has length; derived type has lesser maxLength + @" + + + + + + + + + + + + +" + }, + new object[] + { // base type has length; derived type has greater minLength + @" + + + + + + + + + + + + +" + }, + new object[] + { // base type has maxLength; derived type has greater length + @" + + + + + + + + + + + + +" + } + }; + } + } + + [Theory] + [MemberData(nameof(MaxMinLengthBaseLength_ThrowsData))] + public void MaxMinLengthBaseLength_Throws(string schema) + { + XmlSchemaSet ss = new XmlSchemaSet(); + ss.Add(null, XmlReader.Create(new StringReader(schema))); + + Exception ex = Assert.Throws(() => ss.Compile()); + + Assert.Contains("length", ex.Message); + Assert.Contains("minLength", ex.Message); + Assert.Contains("maxLength", ex.Message); + } + + [Fact] + public void MinLengthGtMaxLength_Throws() + { + string schema = @" + + + + + + + + +"; + XmlSchemaSet ss = new XmlSchemaSet(); + ss.Add(null, XmlReader.Create(new StringReader(schema))); + + Exception ex = Assert.Throws(() => ss.Compile()); + + Assert.Contains("minLength", ex.Message); + Assert.Contains("maxLength", ex.Message); + } + + public static IEnumerable MaxMinLengthBaseLength_Success_TestData + { + get + { + return new List() + { + new object[] + { // base type has length; derived type has equal maxLength + @" + + + + + + + + + + + + +" + }, + new object[] + { // base type has length; derived type has greater maxLength + @" + + + + + + + + + + + + +" + }, + new object[] + { // base type has length; derived type has equal minLength + @" + + + + + + + + + + + + +" + }, + new object[] + { // base type has length; derived type has lesser minLength + @" + + + + + + + + + + + + +" + }, + new object[] + { // base type has minLength; derived type has equal length + @" + + + + + + + + + + + + +" + }, + new object[] + { // base type has minLength; derived type has greater length + @" + + + + + + + + + + + + +" + }, + new object[] + { // base type has maxLength; derived type has equal length + @" + + + + + + + + + + + + +" + }, + new object[] + { // base type has maxLength; derived type has lesser length + @" + + + + + + + + + + + + +" + }, + new object[] + { // minLength is equal to maxLength + @" + + + + + + + + +" + }, + new object[] + { // minLength is less than maxLength + @" + + + + + + + + +" + } + }; + } + } + + [Theory] + [MemberData(nameof(MaxMinLengthBaseLength_Success_TestData))] + public void MaxMinLengthBaseLength_Test(string schema) + { + XmlSchemaSet ss = new XmlSchemaSet(); + ss.Add(null, XmlReader.Create(new StringReader(schema))); + + ss.Compile(); + + Assert.True(true); + } + #endregion + + [Fact] + public void LengthGtBaseLength_Throws() + { + string schema = @" + + + + + + + + + + + + +"; + + XmlSchemaSet ss = new XmlSchemaSet(); + ss.Add(null, XmlReader.Create(new StringReader(schema))); + + Exception ex = Assert.Throws(() => ss.Compile()); + + Assert.Contains("length", ex.Message); + } + + #region FacetBaseFixed tests + public static IEnumerable FacetBaseFixed_Throws_TestData + { + get{ + return new List() + { + new object[] + { // length, derived type has larger value. + @" + + + + + + + + + + + + +" + }, + new object[] + { // length, derived type has smaller value + @" + + + + + + + + + + + + +" + }, + new object[] + { // minLength, derived type has larger value. + @" + + + + + + + + + + + + +" + }, + new object[] + { // minLength, derived type has smaller value. + @" + + + + + + + + + + + + +" + }, + new object[] + { // maxLength, derived type has lower value. + @" + + + + + + + + + + + + +" + }, + new object[] + { // maxLength, derived type has larger value. + @" + + + + + + + + + + + + +" + }, + new object[] + { // whiteSpace + @" + + + + + + + + + + + + +" + }, + new object[] + { // maxInclusive, derived type with larger value + @" + + + + + + + + + + + + +" + }, + new object[] + { // maxInclusive, derived type with smaller value + @" + + + + + + + + + + + + +" + }, + new object[] + { // maxExclusive, derived type has larger value + @" + + + + + + + + + + + + +" + }, + new object[] + { // maxExclusive, derived type has smaller value + @" + + + + + + + + + + + + +" + }, + new object[] + { // minExclusive, derived type has larger value + @" + + + + + + + + + + + + +" + }, + new object[] + { // minExclusive, derived type has smaller value + @" + + + + + + + + + + + + +" + }, + new object[] + { // minInclusive, derived type has larger value + @" + + + + + + + + + + + + +" + }, + new object[] + { // minInclusive, derived type has smaller value + @" + + + + + + + + + + + + +" + } + }; + } + } + + [Theory] + [MemberData(nameof(FacetBaseFixed_Throws_TestData))] + public void FacetBaseFixed_Throws(string schema) + { + XmlSchemaSet ss = new XmlSchemaSet(); + ss.Add(null, XmlReader.Create(new StringReader(schema))); + + Exception ex = Assert.Throws(() => ss.Compile()); + Assert.Contains("fixed='true'", ex.Message); + } + #endregion + + [Fact] + public void InvalidAllMax_Throws() + { + string schema = @" + + + + + + + + +"; + XmlReader xr; + xr = XmlReader.Create(new StringReader(schema)); + XmlSchemaSet ss = new XmlSchemaSet(); + + Exception ex = Assert.Throws(() => ss.Add(null, xr)); + + Assert.Contains("all", ex.Message); + } + + [Fact] + public void InvalidAllElementMax_Throws() + { + string schema = @" + + + + + + + + +"; + XmlReader xr; + xr = XmlReader.Create(new StringReader(schema)); + XmlSchemaSet ss = new XmlSchemaSet(); + + Exception ex = Assert.Throws(() => ss.Add(null, xr)); + + Assert.Contains("all", ex.Message); + Assert.Contains("maxOccurs", ex.Message); + } + + [Fact] + public void InvalidExemplar_Throws() + { + string schema = @" + + + + + + + + + + +"; + + XmlReader xr; + xr = XmlReader.Create(new StringReader(schema)); + XmlSchemaSet ss = new XmlSchemaSet(); + ss.Add(null, xr); + + Exception ex = Assert.Throws(() => ss.Compile()); + + Assert.Contains("substitutionGroup", ex.Message); + Assert.Contains("person", ex.Message); + } + + [Fact] + public void GroupBaseRestNotEmptiable_Throws() + { + string schema = @" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + XmlSchemaSet ss = new XmlSchemaSet(); + ss.Add(null, XmlReader.Create(new StringReader(schema))); + + Exception ex = Assert.Throws(() => ss.Compile()); + + Assert.Contains("particle", ex.Message); + } + + #region test throwing of XmlSchemaException with message Sch_AllRefMinMax + public static IEnumerable AllRefMinMax_Throws_TestData + { + get + { + return new List() + { + new object[] + { // invalid value for minOccurs and maxOccurs +@" + + + + + + + + + + + + + +" + }, + new object[] + { // maxOccurs too large +@" + + + + + + + + + + + + + +" + } + }; + } + } + + [Theory] + [MemberData(nameof(AllRefMinMax_Throws_TestData))] + public void AllRefMinMax_Throws(string schema) + { + XmlSchemaSet ss = new XmlSchemaSet(); + ss.Add(null, XmlReader.Create(new StringReader(schema))); + + Exception ex = Assert.Throws(() => ss.Compile()); + + Assert.Contains("all", ex.Message); + Assert.Contains("minOccurs", ex.Message); + Assert.Contains("maxOccurs", ex.Message); + } + #endregion } }