Multiple schemas in wsdl could share same SourceUri, so check more identity.
authorAtsushi Eno <atsushi@ximian.com>
Mon, 9 May 2011 10:09:19 +0000 (19:09 +0900)
committerAtsushi Eno <atsushi@ximian.com>
Mon, 9 May 2011 10:09:19 +0000 (19:09 +0900)
Part of bugfix #670945.

mcs/class/System.XML/System.Xml.Schema/XmlSchema.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaObject.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSet.cs
mcs/class/System.XML/Test/System.Xml.Schema/XmlSchemaSetTests.cs

index 13b8b9f6a71cbac42a00b7a410e5229d77c83013..6f1a4c40dd6be05c9cff4665873e1a9f01fc8a50 100644 (file)
@@ -28,6 +28,7 @@
 //
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Xml;
 using System.IO;
 using System.Xml.Serialization;
@@ -291,21 +292,30 @@ namespace System.Xml.Schema
                // It is used by XmlSchemaCollection.Add() and XmlSchemaSet.Remove().
                internal void CompileSubset (ValidationEventHandler handler, XmlSchemaSet col, XmlResolver resolver)
                {
-                       Hashtable handledUris = new Hashtable ();
+                       var handledUris = new List<CompiledSchemaMemo> ();
                        CompileSubset (handler, col, resolver, handledUris);
                }
 
                // It is used by XmlSchemaSet.Compile().
-               internal void CompileSubset (ValidationEventHandler handler, XmlSchemaSet col, XmlResolver resolver, Hashtable handledUris)
+               internal void CompileSubset (ValidationEventHandler handler, XmlSchemaSet col, XmlResolver resolver, List<CompiledSchemaMemo> handledUris)
                {
                        if (SourceUri != null && SourceUri.Length > 0) {
-                               if (handledUris.Contains (SourceUri))
+                               // if it has line info and are the same as one of existing info, then skip it.
+                               if (Contains (handledUris))
                                        return;
-                               handledUris.Add (SourceUri, SourceUri);
+                               handledUris.Add (new CompiledSchemaMemo () {  SourceUri = this.SourceUri, LineNumber = this.LineNumber, LinePosition = this.LinePosition});
                        }
                        DoCompile (handler, handledUris, col, resolver);
                }
 
+               bool Contains (List<CompiledSchemaMemo> handledUris)
+               {
+                       foreach (var i in handledUris)
+                               if (i.SourceUri.Equals (SourceUri) && i.LineNumber != 0 && i.LineNumber == LineNumber && i.LinePosition == LinePosition)
+                                       return true;
+                       return false;
+               }
+
                void SetParent ()
                {
                        for (int i = 0; i < Items.Count; i++)
@@ -314,7 +324,7 @@ namespace System.Xml.Schema
                                Includes [i].SetParent (this);
                }
 
-               void DoCompile (ValidationEventHandler handler, Hashtable handledUris, XmlSchemaSet col, XmlResolver resolver)
+               void DoCompile (ValidationEventHandler handler, List<CompiledSchemaMemo> handledUris, XmlSchemaSet col, XmlResolver resolver)
                {
                        SetParent ();
                        CompilationId = col.CompilationId;
@@ -477,7 +487,7 @@ namespace System.Xml.Schema
 #endif
                }
 
-               void ProcessExternal (ValidationEventHandler handler, Hashtable handledUris, XmlResolver resolver, XmlSchemaExternal ext, XmlSchemaSet col)
+               void ProcessExternal (ValidationEventHandler handler, List<CompiledSchemaMemo> handledUris, XmlResolver resolver, XmlSchemaExternal ext, XmlSchemaSet col)
                {
                        if (ext == null) {
                                error (handler, String.Format ("Object of Type {0} is not valid in Includes Property of XmlSchema", ext.GetType().Name));
@@ -496,10 +506,11 @@ namespace System.Xml.Schema
                                string url = null;
                                if (resolver != null) {
                                        url = GetResolvedUri (resolver, ext.SchemaLocation);
-                                       if (handledUris.Contains (url))
-                                               // This schema is already handled, so simply skip (otherwise, duplicate definition errrors occur.
-                                               return;
-                                       handledUris.Add (url, url);
+                                       foreach (var i in handledUris)
+                                               if (i.SourceUri.Equals (url))
+                                                       // This schema is already handled, so simply skip (otherwise, duplicate definition errrors occur.
+                                                       return;
+                                       handledUris.Add (new CompiledSchemaMemo () { SourceUri = url });
                                        try {
                                                stream = resolver.GetEntity (new Uri (url), null, typeof (Stream)) as Stream;
                                        } catch (Exception) {
@@ -589,7 +600,7 @@ namespace System.Xml.Schema
                }
 
 
-               void AddExternalComponentsTo (XmlSchema s, XmlSchemaObjectCollection items, ValidationEventHandler handler, Hashtable handledUris, XmlResolver resolver, XmlSchemaSet col)
+               void AddExternalComponentsTo (XmlSchema s, XmlSchemaObjectCollection items, ValidationEventHandler handler, List<CompiledSchemaMemo> handledUris, XmlResolver resolver, XmlSchemaSet col)
                {
                        foreach (XmlSchemaExternal ext in s.Includes)
                                s.ProcessExternal (handler, handledUris, resolver, ext, col);
@@ -992,4 +1003,11 @@ namespace System.Xml.Schema
                        return new XmlSchemaSerializationWriter ();
                }
        }
+       
+       class CompiledSchemaMemo
+       {
+               public string SourceUri;
+               public int LineNumber;
+               public int LinePosition;
+       }
 }
index 6f1f3f7ebfade6e542d1cf026a779c1745d398a9..d3de335fb9b13dd16de26bed2092d9691e99d7bc 100644 (file)
@@ -45,7 +45,7 @@ namespace System.Xml.Schema
                internal ArrayList unhandledAttributeList ;
                internal bool isCompiled = false;
                internal int errorCount = 0;
-               internal Guid CompilationId;
+               internal Guid compilation_id;
                internal Guid ValidationId;
                internal bool isRedefineChild;
                internal bool isRedefinedComponent;
@@ -58,7 +58,16 @@ namespace System.Xml.Schema
                {
                        namespaces = new XmlSerializerNamespaces();
                        unhandledAttributeList = null;
-                       CompilationId = Guid.Empty;
+                       compilation_id = Guid.Empty;
+               }
+               
+               internal Guid CompilationId {
+                       get { return compilation_id; }
+                       set {
+                               if (value.Equals (Guid.Empty))
+                                       throw new ArgumentException ("value must not be empty");
+                               compilation_id = value;
+                       }
                }
 
                [XmlIgnore]
index c304f4cb17322a1280e6093efb6b77109a9703ad..2088dd60b0ec12824e4b2e3b2fd639805d9c7eb3 100644 (file)
@@ -30,6 +30,7 @@
 //
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.ComponentModel;
 using System.IO;
@@ -62,7 +63,7 @@ namespace System.Xml.Schema
 
                bool isCompiled;
 
-               internal Guid CompilationId;
+               internal Guid CompilationId { get; private set; }
 
                public XmlSchemaSet ()
                        : this (new NameTable ())
@@ -199,7 +200,7 @@ namespace System.Xml.Schema
                        IDCollection.Clear ();
                        NamedIdentities.Clear ();
 
-                       Hashtable handledUris = new Hashtable ();
+                       var handledUris = new List<CompiledSchemaMemo> ();
                        foreach (XmlSchema schema in al)
                                if (!schema.IsCompiled)
                                        schema.CompileSubset (ValidationEventHandler, this, xmlResolver, handledUris);
index d5078cbc5afd0fc4b1e521345167fbec865e6f26..6a8a7a49d8accf2b444cc3efc26ae861e332e194 100644 (file)
@@ -218,6 +218,67 @@ type=""xsd:string"" use=""required""/>
                        var xsd = schemas.Add ("", XmlReader.Create (new StringReader (xsdraw)));
                        Assert.IsNull (xsd.TargetNamespace, "#1");
                }
+
+               [Test] // part of bug #670945
+               public void TwoSchemasInSameDocumentUri ()
+               {
+                       string xsd1 = @"
+    <xs:schema
+    targetNamespace='http://www.onvif.org/ver10/schema'
+    elementFormDefault='qualified'
+    xmlns:xs='http://www.w3.org/2001/XMLSchema'
+    xmlns:tt='http://www.onvif.org/ver10/schema'>
+
+      <xs:complexType name='SystemDateTime'>
+        <xs:sequence>
+          <xs:element name='foobar' type='xs:string' minOccurs='0' />
+          <xs:element name='Extension' type='tt:SystemDateTimeExtension' minOccurs='0'/>
+        </xs:sequence>
+        <!-- xs:anyAttribute processContents='lax'/ -->
+      </xs:complexType>
+
+      <xs:complexType name='SystemDateTimeExtension'>
+        <xs:sequence>
+          <xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded'/>
+        </xs:sequence>
+      </xs:complexType>
+
+    </xs:schema>";
+
+                       string xsd2 = @"
+    <xs:schema
+      targetNamespace='http://www.onvif.org/ver10/device/wsdl'
+      xmlns:xs='http://www.w3.org/2001/XMLSchema'
+      xmlns:tt='http://www.onvif.org/ver10/schema'
+      xmlns:tds='http://www.onvif.org/ver10/device/wsdl' 
+      elementFormDefault='qualified'>
+      <xs:element name='GetSystemDateAndTime'>
+        <xs:complexType>
+          <xs:sequence/>
+
+        </xs:complexType>
+      </xs:element>
+      <xs:element name='GetSystemDateAndTimeResponse'>
+        <xs:complexType>
+          <xs:sequence>
+            <xs:element name='SystemDateAndTime' type='tt:SystemDateTime' />
+          </xs:sequence>
+        </xs:complexType>
+      </xs:element>
+    </xs:schema>";
+
+                       var xss = new XmlSchemaSet ();
+                       var xs1 = XmlSchema.Read (new StringReader (xsd1), null);
+                       xs1.SourceUri = "http://localhost:8080/dummy.wsdl";
+                       xs1.LineNumber = 5;
+                       xss.Add (xs1);
+                       var xs2 = XmlSchema.Read (new StringReader (xsd2), null);
+                       xs2.SourceUri = "http://localhost:8080/dummy.wsdl";
+                       xs2.LineNumber = 50;
+                       xss.Add (xs2);
+                       xss.Compile ();
+                       Assert.IsNotNull (xss.GlobalElements [new XmlQualifiedName ("GetSystemDateAndTimeResponse", "http://www.onvif.org/ver10/device/wsdl")], "#1");
+               }
        }
 }
 #endif