Author: nicko Date: Mon Feb 20 11:49:25 2006 New Revision: 379212 URL: http://svn.apache.org/viewcvs?rev=379212&view=rev Log: Fix for LOG4NET-65 Unhandled SecurityException exception for FileIOPermission while loading configuration file Added additional try/catch blocks to the DefaultRepositorySelector and the XmlConfiguratorAttribute to wrap any path discovery permission checks made by the AppDomain.
Modified: logging/log4net/trunk/src/Config/XmlConfiguratorAttribute.cs logging/log4net/trunk/src/Core/DefaultRepositorySelector.cs logging/log4net/trunk/src/Util/SystemInfo.cs Modified: logging/log4net/trunk/src/Config/XmlConfiguratorAttribute.cs URL: http://svn.apache.org/viewcvs/logging/log4net/trunk/src/Config/XmlConfiguratorAttribute.cs?rev=379212&r1=379211&r2=379212&view=diff ============================================================================== --- logging/log4net/trunk/src/Config/XmlConfiguratorAttribute.cs (original) +++ logging/log4net/trunk/src/Config/XmlConfiguratorAttribute.cs Mon Feb 20 11:49:25 2006 @@ -196,9 +196,18 @@ /// <exception cref="ArgumentOutOfRangeException">The <paramref name="repository" /> does not extend <see cref="Hierarchy"/>.</exception> override public void Configure(Assembly sourceAssembly, ILoggerRepository targetRepository) { - Uri applicationBaseDirectoryUri = new Uri(SystemInfo.ApplicationBaseDirectory); + string applicationBaseDirectory = null; + try + { + applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory; + } + catch + { + // Ignore this exception because it is only thrown when ApplicationBaseDirectory is a file + // and the application does not have PathDiscovery permission + } - if (applicationBaseDirectoryUri.IsFile) + if (applicationBaseDirectory == null || (new Uri(applicationBaseDirectory)).IsFile) { ConfigureFromFile(sourceAssembly, targetRepository); } @@ -226,7 +235,14 @@ if (m_configFileExtension == null || m_configFileExtension.Length == 0) { // Use the default .config file for the AppDomain - fullPath2ConfigFile = SystemInfo.ConfigurationFileLocation; + try + { + fullPath2ConfigFile = SystemInfo.ConfigurationFileLocation; + } + catch(Exception ex) + { + LogLog.Error("XmlConfiguratorAttribute: Exception getting ConfigurationFileLocation. Must be able to resolve ConfigurationFileLocation when ConfigFile and ConfigFileExtension properties are not set.", ex); + } } else { @@ -236,16 +252,49 @@ m_configFileExtension = "." + m_configFileExtension; } - fullPath2ConfigFile = Path.Combine(SystemInfo.ApplicationBaseDirectory, SystemInfo.AssemblyFileName(sourceAssembly) + m_configFileExtension); + string applicationBaseDirectory = null; + try + { + applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory; + } + catch(Exception ex) + { + LogLog.Error("XmlConfiguratorAttribute: Exception getting ApplicationBaseDirectory. Must be able to resolve ApplicationBaseDirectory and AssemblyFileName when ConfigFileExtension property is set.", ex); + } + + if (applicationBaseDirectory != null) + { + fullPath2ConfigFile = Path.Combine(applicationBaseDirectory, SystemInfo.AssemblyFileName(sourceAssembly) + m_configFileExtension); + } } } else { - // Just the base dir + the config file - fullPath2ConfigFile = Path.Combine(SystemInfo.ApplicationBaseDirectory, m_configFile); + string applicationBaseDirectory = null; + try + { + applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory; + } + catch(Exception ex) + { + LogLog.Warn("XmlConfiguratorAttribute: Exception getting ApplicationBaseDirectory. ConfigFile property path ["+m_configFile+"] will be treated as an absolute path.", ex); + } + + if (applicationBaseDirectory != null) + { + // Just the base dir + the config file + fullPath2ConfigFile = Path.Combine(applicationBaseDirectory, m_configFile); + } + else + { + fullPath2ConfigFile = m_configFile; + } } - ConfigureFromFile(targetRepository, new FileInfo(fullPath2ConfigFile)); + if (fullPath2ConfigFile != null) + { + ConfigureFromFile(targetRepository, new FileInfo(fullPath2ConfigFile)); + } } /// <summary> @@ -281,9 +330,6 @@ /// <param name="targetRepository">The repository to configure.</param> private void ConfigureFromUri(Assembly sourceAssembly, ILoggerRepository targetRepository) { - Uri applicationBaseDirectoryUri = new Uri(SystemInfo.ApplicationBaseDirectory); - Uri systemConfigFileUri = new Uri(SystemInfo.ConfigurationFileLocation); - // Work out the full path to the config file Uri fullPath2ConfigFile = null; @@ -292,8 +338,23 @@ { if (m_configFileExtension == null || m_configFileExtension.Length == 0) { - // Use the default .config file for the AppDomain - fullPath2ConfigFile = systemConfigFileUri; + string systemConfigFilePath = null; + try + { + systemConfigFilePath = SystemInfo.ConfigurationFileLocation; + } + catch(Exception ex) + { + LogLog.Error("XmlConfiguratorAttribute: Exception getting ConfigurationFileLocation. Must be able to resolve ConfigurationFileLocation when ConfigFile and ConfigFileExtension properties are not set.", ex); + } + + if (systemConfigFilePath != null) + { + Uri systemConfigFileUri = new Uri(systemConfigFilePath); + + // Use the default .config file for the AppDomain + fullPath2ConfigFile = systemConfigFileUri; + } } else { @@ -303,40 +364,73 @@ m_configFileExtension = "." + m_configFileExtension; } - UriBuilder builder = new UriBuilder(systemConfigFileUri); - - // Remove the current extension from the systemConfigFileUri path - string path = builder.Path; - int startOfExtension = path.LastIndexOf("."); - if (startOfExtension >= 0) + string systemConfigFilePath = null; + try + { + systemConfigFilePath = SystemInfo.ConfigurationFileLocation; + } + catch(Exception ex) { - path = path.Substring(0, startOfExtension); + LogLog.Error("XmlConfiguratorAttribute: Exception getting ConfigurationFileLocation. Must be able to resolve ConfigurationFileLocation when the ConfigFile property are not set.", ex); } - path += m_configFileExtension; - builder.Path = path; - fullPath2ConfigFile = builder.Uri; + if (systemConfigFilePath != null) + { + UriBuilder builder = new UriBuilder(new Uri(systemConfigFilePath)); + + // Remove the current extension from the systemConfigFileUri path + string path = builder.Path; + int startOfExtension = path.LastIndexOf("."); + if (startOfExtension >= 0) + { + path = path.Substring(0, startOfExtension); + } + path += m_configFileExtension; + + builder.Path = path; + fullPath2ConfigFile = builder.Uri; + } } } else { - // Just the base dir + the config file - fullPath2ConfigFile = new Uri(applicationBaseDirectoryUri, m_configFile); - } + string applicationBaseDirectory = null; + try + { + applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory; + } + catch(Exception ex) + { + LogLog.Warn("XmlConfiguratorAttribute: Exception getting ApplicationBaseDirectory. ConfigFile property path ["+m_configFile+"] will be treated as an absolute URI.", ex); + } - if (fullPath2ConfigFile.IsFile) - { - // The m_configFile could be an absolute local path, therefore we have to be - // prepared to switch back to using FileInfos here - ConfigureFromFile(targetRepository, new FileInfo(fullPath2ConfigFile.LocalPath)); + if (applicationBaseDirectory != null) + { + // Just the base dir + the config file + fullPath2ConfigFile = new Uri(new Uri(applicationBaseDirectory), m_configFile); + } + else + { + fullPath2ConfigFile = new Uri(m_configFile); + } } - else + + if (fullPath2ConfigFile != null) { - if (m_configureAndWatch) + if (fullPath2ConfigFile.IsFile) { - LogLog.Warn("XmlConfiguratorAttribute: Unable to watch config file loaded from a URI"); + // The m_configFile could be an absolute local path, therefore we have to be + // prepared to switch back to using FileInfos here + ConfigureFromFile(targetRepository, new FileInfo(fullPath2ConfigFile.LocalPath)); + } + else + { + if (m_configureAndWatch) + { + LogLog.Warn("XmlConfiguratorAttribute: Unable to watch config file loaded from a URI"); + } + XmlConfigurator.Configure(targetRepository, fullPath2ConfigFile); } - XmlConfigurator.Configure(targetRepository, fullPath2ConfigFile); } } Modified: logging/log4net/trunk/src/Core/DefaultRepositorySelector.cs URL: http://svn.apache.org/viewcvs/logging/log4net/trunk/src/Core/DefaultRepositorySelector.cs?rev=379212&r1=379211&r2=379212&view=diff ============================================================================== --- logging/log4net/trunk/src/Core/DefaultRepositorySelector.cs (original) +++ logging/log4net/trunk/src/Core/DefaultRepositorySelector.cs Mon Feb 20 11:49:25 2006 @@ -290,20 +290,26 @@ rep = m_name2repositoryMap[actualRepositoryName] as ILoggerRepository; if (rep == null) { - // Create the repository rep = CreateRepository(actualRepositoryName, actualRepositoryType); if (readAssemblyAttributes) { - // Look for aliasing attributes - LoadAliases(repositoryAssembly, rep); - - // Look for plugins defined on the assembly - LoadPlugins(repositoryAssembly, rep); - - // Configure the repository using the assembly attributes - ConfigureRepository(repositoryAssembly, rep); + try + { + // Look for aliasing attributes + LoadAliases(repositoryAssembly, rep); + + // Look for plugins defined on the assembly + LoadPlugins(repositoryAssembly, rep); + + // Configure the repository using the assembly attributes + ConfigureRepository(repositoryAssembly, rep); + } + catch (Exception ex) + { + LogLog.Error("DefaultRepositorySelector: Failed to configure repository [" + actualRepositoryName + "] from assembly attributes.", ex); + } } } else @@ -312,8 +318,15 @@ if (readAssemblyAttributes) { - // Look for plugins defined on the assembly - LoadPlugins(repositoryAssembly, rep); + try + { + // Look for plugins defined on the assembly + LoadPlugins(repositoryAssembly, rep); + } + catch (Exception ex) + { + LogLog.Error("DefaultRepositorySelector: Failed to configure repository [" + actualRepositoryName + "] from assembly attributes.", ex); + } } } m_assembly2repositoryMap[repositoryAssembly] = rep; @@ -556,51 +569,65 @@ throw new ArgumentNullException("assembly"); } - LogLog.Debug("DefaultRepositorySelector: Assembly [" + assembly.FullName + "] Loaded From [" + SystemInfo.AssemblyLocationInfo(assembly) + "]"); - - // Look for the RepositoryAttribute on the assembly - object[] repositoryAttributes = Attribute.GetCustomAttributes(assembly, typeof(log4net.Config.RepositoryAttribute), false); - if (repositoryAttributes == null || repositoryAttributes.Length == 0) + try { - // This is not a problem, but its nice to know what is going on. - LogLog.Debug("DefaultRepositorySelector: Assembly [" + assembly + "] does not have a RepositoryAttribute specified."); + LogLog.Debug("DefaultRepositorySelector: Assembly [" + assembly.FullName + "] Loaded From [" + SystemInfo.AssemblyLocationInfo(assembly) + "]"); } - else + catch { - if (repositoryAttributes.Length > 1) - { - LogLog.Error("DefaultRepositorySelector: Assembly [" + assembly + "] has multiple log4net.Config.RepositoryAttribute assembly attributes. Only using first occurrence."); - } - - log4net.Config.RepositoryAttribute domAttr = repositoryAttributes[0] as log4net.Config.RepositoryAttribute; + // Ignore exception from debug call + } - if (domAttr == null) + try + { + // Look for the RepositoryAttribute on the assembly + object[] repositoryAttributes = Attribute.GetCustomAttributes(assembly, typeof(log4net.Config.RepositoryAttribute), false); + if (repositoryAttributes == null || repositoryAttributes.Length == 0) { - LogLog.Error("DefaultRepositorySelector: Assembly [" + assembly + "] has a RepositoryAttribute but it does not!."); + // This is not a problem, but its nice to know what is going on. + LogLog.Debug("DefaultRepositorySelector: Assembly [" + assembly + "] does not have a RepositoryAttribute specified."); } else { - // If the Name property is set then override the default - if (domAttr.Name != null) + if (repositoryAttributes.Length > 1) { - repositoryName = domAttr.Name; + LogLog.Error("DefaultRepositorySelector: Assembly [" + assembly + "] has multiple log4net.Config.RepositoryAttribute assembly attributes. Only using first occurrence."); } - // If the RepositoryType property is set then override the default - if (domAttr.RepositoryType != null) + log4net.Config.RepositoryAttribute domAttr = repositoryAttributes[0] as log4net.Config.RepositoryAttribute; + + if (domAttr == null) { - // Check that the type is a repository - if (typeof(ILoggerRepository).IsAssignableFrom(domAttr.RepositoryType)) + LogLog.Error("DefaultRepositorySelector: Assembly [" + assembly + "] has a RepositoryAttribute but it does not!."); + } + else + { + // If the Name property is set then override the default + if (domAttr.Name != null) { - repositoryType = domAttr.RepositoryType; + repositoryName = domAttr.Name; } - else + + // If the RepositoryType property is set then override the default + if (domAttr.RepositoryType != null) { - LogLog.Error("DefaultRepositorySelector: Repository Type [" + domAttr.RepositoryType + "] must implement the ILoggerRepository interface."); + // Check that the type is a repository + if (typeof(ILoggerRepository).IsAssignableFrom(domAttr.RepositoryType)) + { + repositoryType = domAttr.RepositoryType; + } + else + { + LogLog.Error("DefaultRepositorySelector: Repository Type [" + domAttr.RepositoryType + "] must implement the ILoggerRepository interface."); + } } } } } + catch (Exception ex) + { + LogLog.Error("DefaultRepositorySelector: Unhandled exception in GetInfoForAssembly", ex); + } } /// <summary> @@ -625,7 +652,7 @@ throw new ArgumentNullException("repository"); } - // Look for the Configurator attributes (e.g. DOMConfiguratorAttribute) on the assembly + // Look for the Configurator attributes (e.g. XmlConfiguratorAttribute) on the assembly object[] configAttributes = Attribute.GetCustomAttributes(assembly, typeof(log4net.Config.ConfiguratorAttribute), false); if (configAttributes != null && configAttributes.Length > 0) { @@ -635,7 +662,17 @@ // Delegate to the attribute the job of configuring the repository foreach(log4net.Config.ConfiguratorAttribute configAttr in configAttributes) { - configAttr.Configure(assembly, repository); + if (configAttr != null) + { + try + { + configAttr.Configure(assembly, repository); + } + catch (Exception ex) + { + LogLog.Error("DefaultRepositorySelector: Exception calling ["+configAttr.GetType().FullName+"] .Configure method.", ex); + } + } } } @@ -648,15 +685,30 @@ string repositoryConfigFile = SystemInfo.GetAppSetting("log4net.Config"); if (repositoryConfigFile != null && repositoryConfigFile.Length > 0) { - // Resolve the config path relative to the application base directory URI - Uri applicationBaseDirectoryUri = new Uri(SystemInfo.ApplicationBaseDirectory); + string applicationBaseDirectory = null; + try + { + applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory; + } + catch(Exception ex) + { + LogLog.Warn("DefaultRepositorySelector: Exception getting ApplicationBaseDirectory. appSettings log4net.Config path ["+repositoryConfigFile+"] will be treated as an absolute URI", ex); + } // As we are not going to watch the config file it is easiest to just resolve it as a // URI and pass that to the Configurator Uri repositoryConfigUri = null; try { - repositoryConfigUri = new Uri(applicationBaseDirectoryUri, repositoryConfigFile); + if (applicationBaseDirectory != null) + { + // Resolve the config path relative to the application base directory URI + repositoryConfigUri = new Uri(new Uri(applicationBaseDirectory), repositoryConfigFile); + } + else + { + repositoryConfigUri = new Uri(repositoryConfigFile); + } } catch(Exception ex) { @@ -667,8 +719,15 @@ { LogLog.Debug("DefaultRepositorySelector: Loading configuration for default repository from AppSettings specified Config URI ["+repositoryConfigUri.ToString()+"]"); - // TODO: Support other types of configurator - XmlConfigurator.Configure(repository, repositoryConfigUri); + try + { + // TODO: Support other types of configurator + XmlConfigurator.Configure(repository, repositoryConfigUri); + } + catch (Exception ex) + { + LogLog.Error("DefaultRepositorySelector: Exception calling XmlConfigurator.Configure method with ConfigUri ["+repositoryConfigUri+"]", ex); + } } } } Modified: logging/log4net/trunk/src/Util/SystemInfo.cs URL: http://svn.apache.org/viewcvs/logging/log4net/trunk/src/Util/SystemInfo.cs?rev=379212&r1=379211&r2=379212&view=diff ============================================================================== --- logging/log4net/trunk/src/Util/SystemInfo.cs (original) +++ logging/log4net/trunk/src/Util/SystemInfo.cs Mon Feb 20 11:49:25 2006 @@ -888,7 +888,7 @@ } catch { - // ignore uri exceptions + // Ignore URI exceptions & SecurityExceptions from SystemInfo.ApplicationBaseDirectory } if (baseDirectory != null && baseDirectory.Length > 0)