odata.net icon indicating copy to clipboard operation
odata.net copied to clipboard

EdmLib successfully parses type names with unbalanced parens

Open mikepizzo opened this issue 11 months ago • 1 comments

TypeNames with unbalance parens, for example:

Type="Collection(ns.myType" or Type="ns.myType)"

parse just fine.

Assemblies affected

Microsoft.OData.Edm 7.x

Reproduce steps

Save the following xml as "badschema.csdl":

<?xml version="1.0" encoding="utf-8" ?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
    <edmx:DataServices>
        <Schema Namespace="namespace" Alias="ns" xmlns="http://docs.oasis-open.org/odata/ns/edm">
			<ComplexType Name="myPropType"/>
			<ComplexType Name="myType">
				<Property Name="prop1" Type="ns.myType)" />
				<Property Name="prop2" Type="Collection(ns.myType" />
			</ComplexType>
		</Schema>
    </edmx:DataServices>
</edmx:Edmx>

run the following:

static void Main(string[] args)
{
    IEdmModel model;
    IEnumerable<EdmError> errors;
    using (var stream = File.Open("badschema.csdl", FileMode.Open))
    {
        using (XmlReader reader = XmlReader.Create(stream))
        {
            var success = CsdlReader.TryParse(reader, out model, out errors);
            if (success & model.Validate(out errors))
            {
                var myType = model.SchemaElements.FirstOrDefault(e => e.Name == "myType") as IEdmStructuredType;
                if (myType != null)
                {
                    Console.WriteLine("Found type 'myType'");
                    foreach (var prop in myType.StructuralProperties())
                    {
                        Console.WriteLine("Property Name={0}, Type={1}", prop.Name, prop.Type.FullName());
                    }
                }
            }
            else
            {
                WriteErrors(errors);
            }
        }
    }
}

Expected result

Error reading the property type names.

Actual result

Found type 'myType' Property Name=prop1, Type=namespace.myType Property Name=prop2, Type=Collection(namespace.myType)

Additional detail

"bug" is in EdmXmlDocumentParser.ValidateTypeName. The algorithm is:

  1. split on '(',')'
  2. If first segment is "Collection", then return second segment as typename, otherwise return the first segment as typename.

So, in either case, the extra paren is parsed away, so validate succeeds.

Next, we try and parse the type reference, using the same logic -- first split on '{','}', then return first or second segment depending on whether first segment is "collection". So, again, extra parens are lost and the parse succeeds with the desired (if not expected) value.

!!probably can't fix this in a minor release as it could break existing schemas that had this particular typo and are working correctly today!!

mikepizzo avatar Mar 15 '24 21:03 mikepizzo

Consider the following invalid cases too:

  • (ns.myType)
  • ns.myType)
  • (ns.myType

gathogojr avatar Mar 19 '24 16:03 gathogojr