首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在深度嵌套xml上调用StackOverflowException时的XmlElement.OuterXml

在深度嵌套xml上调用StackOverflowException时的XmlElement.OuterXml
EN

Stack Overflow用户
提问于 2010-08-27 15:45:04
回答 1查看 513关注 0票数 2

我在验证WebService上的一些XML输入数据时遇到了问题。我包括了你需要的一切来重现错误,所以希望有人能帮助我。提前谢谢你!

我有一些黑客给我发送了一些无效的XML到我的公共接口,它没有在我的XSD验证中被检测到,而是在它到达XSD之前就使整个WebApp崩溃了,我无法绕过它!以下是他发送的XML:

代码语言:javascript
复制
<?xml version="1.0"?>
<Security xmlns="">
    <SecurityPermissions>
        <SecurityPermission ActionID="90" Value="1"></SecurityPermission>
        <SecurityPermission ActionID="80" Value="1"></SecurityPermission>
    </SecurityPermissions>
    <C><C><C><C><C>...</C></C></C></C></C>
</Security>

无效的是嵌套的节点。我在这里缩短了XML,但它们类似于1000级别。

对于完整的XML,请下载这里

对于XSD文件,请下载它这里

以下是XSD模式:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema targetNamespace="UpdatePermissions.xsd" xmlns="UpdatePermissions.xsd" xmlns:mstns="UpdatePermissions.xsd" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" >
    <xs:element name="Security">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="SecurityPermissions" minOccurs="1" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="SecurityPermission" minOccurs="0" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:attribute name="ActionID" type="xs:int" use="required" />
                                    <xs:attribute name="Value" type="xs:int" use="required" />
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

要点:

由于XML输入具有xmlns="“(这是我的所有客户端传递它的方式),所以我被迫使用一个新的xmlns值(我将其设置为xmlns="UpdatePermissions.xsd")来修改输入的XML,以使XSD验证工作。由于不能仅仅在现有的XmlElement上设置xmlns,所以我必须将XML复制到XmlDocumentFragment。这与嵌套的节点一起,正在用StackOverflowException破坏我的应用程序,而try..catch是无法捕捉到的。看上去是这样的:

代码语言:javascript
复制
    [WebMethod]
    public XmlElement UpdatePermissions(XmlElement xInput)
    {
        var errors = ValidateUpdatePermissionsXml(xInput);

        if (errors.Count > 0)
            throw new Exception(" I hate everything");

        // do other processing

        return xInput;
    }


    public List<string> ValidateUpdatePermissionsXml(XmlElement xInput)
    {
        // set xmlns since it isn't provided by caller but we need it to validate against XSD
        xInput.SetAttribute("xmlns", "UpdatePermissions.xsd");

        // transfer XML to a fragment otherwise xmlns attribute we set wouldn't take effect
        var fragment = xInput.OwnerDocument.CreateDocumentFragment();
        var xmlString = xInput.OuterXml; //  <---- THIS IS WHERE THE APP CRASHES
        fragment.InnerXml = xmlString;

        //setup errors array
        var errors = new List<string>();

        //read in schema
        var schemaStream = File.OpenRead(@"c:\UpdatePermissions.xsd");
        var schema = XmlSchema.Read(schemaStream, null);
        var schemaSet = new XmlSchemaSet();
        schemaSet.Add(schema);

        //setup validation settings
        var readerSettings = new XmlReaderSettings();
        readerSettings.ValidationType = ValidationType.Schema;
        readerSettings.Schemas = schemaSet;
        readerSettings.ValidationEventHandler += (s, e) => errors.Add(e.Exception.Message);

        //create readers
        var nodeReader = new XmlNodeReader(fragment);
        var reader = XmlReader.Create(nodeReader, readerSettings);

        //read
        while (reader.Read()) ;

        return errors;
    }

下面是我的单元测试,它总是失败:

代码语言:javascript
复制
    [TestMethod]
    public void TestXSDValidation_Invalid_DeeplyNestedNodes()
    {
        //load Xml from file into XmlElement
        var badXml = File.ReadAllText(@"c:\UpdatePermissions_BadRequest.xml");
        var doc = new XmlDocument();
        doc.LoadXml(badXml);
        var badElement = doc.DocumentElement;

        var errors = ValidateUpdatePermissionsXml(badElement);

        Assert.AreEqual(1, errors.Count);
        Assert.AreEqual("The element 'SecurityPermissions' in namespace 'UpdatePermissions.xsd' has invalid child element 'C' in namespace 'UpdatePermissions.xsd'. List of possible elements expected: 'SecurityPermission' in namespace 'UpdatePermissions.xsd'.", errors[0]);
    }

由于节点嵌套的深度,对.OuterXml的调用似乎在StackOverflowException中失败。我通过其他方式将XML写入字符串的所有尝试都失败了。

问题

我无法理解的是,我如何能够接受具有空xmlns属性值的XML,并且仍然可以进行验证,而不必将XML复制到片段中。我尝试过的以某种方式写出XML的所有东西都失败了,应用程序崩溃了。试一试,你就会明白我的意思!

EN

回答 1

Stack Overflow用户

发布于 2011-01-26 13:06:06

与其尝试将整个请求转换为字符串,不如使用请求流的XmlTextReader解析xml?这里有一篇文章提供了这个类的更多细节:

http://support.microsoft.com/kb/307548

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3585866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档