首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

System.Configuration 自訂配置節遞迴 Bug 導致 StackOverflowException 解析

     編輯:關於.NET

問題現象

在 .NET Framework 2.0 中,當自訂配置節 (ConfigurationSection) 使用樹狀結構 (即 ConfigurationElement 巢狀參考自身類型) 時,存取該屬性會拋出 System.StackOverflowException,導致程序崩潰。

重現程式碼

public class NodeElement : ConfigurationElement
{
    [ConfigurationProperty("text", IsRequired = true)]
    public string Text => (string)this["text"];

    [ConfigurationProperty("child")]
    public NodeElement ChildElement => (NodeElement)this["child"];
}

static class Program
{
    [STAThread]
    static void Main()
    {
        NodeElement node = new NodeElement();
        object o = node.ChildElement; // 此處拋出 StackOverflowException
    }
}

根因分析

使用 .NET Reflector 反編譯 System.Configuration.ConfigurationElement 原始碼發現,其內部方法 CreateConfigurationPropertyFromAttributes 在建立 ConfigurationProperty 時,缺少對「屬性類型是否為當前類型」的判斷。當屬性型別為 ConfigurationElement 衍生類且指向自身時,PropertiesFromType 會陷入無限遞迴。

關鍵原始碼片段

private static ConfigurationProperty CreateConfigurationPropertyFromAttributes(PropertyInfo propertyInformation)
{
    ConfigurationProperty property = null;
    if (Attribute.GetCustomAttribute(propertyInformation, typeof(ConfigurationPropertyAttribute)) is ConfigurationPropertyAttribute)
    {
        property = new ConfigurationProperty(propertyInformation);
    }
    // 缺少 property.Type 與當前類型的比較判斷
    if ((property != null) && typeof(ConfigurationElement).IsAssignableFrom(property.Type))
    {
        ConfigurationPropertyCollection result = null;
        PropertiesFromType(property.Type, out result); // 無限遞迴入口
    }
    return property;
}

解決方案與建議

  • 避免自我巢狀:設計配置節時,勿讓 ConfigurationElement 直接或間接參考自身型別。
  • 使用集合替代:改用 ConfigurationElementCollection 管理子節點集合,而非單一巢狀屬性。
  • 升級框架:此問題在 .NET Framework 4.0 及以上版本已修復,建議升級專案目標框架。

總結

此為 .NET Framework 2.0 基礎類別庫的已知缺陷。開發自訂配置節時,務必注意型別參考關係,避免觸發內部遞迴邏輯導致堆疊溢位。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved