Author: nicko
Date: Mon Jul 10 04:46:26 2006
New Revision: 420499

URL: http://svn.apache.org/viewvc?rev=420499&view=rev
Log:
Fix for LOG4NET-79. Added catch handler for SecurityException in 
LogicalThreadContextProperties GetProperties method. This is caused by a 
LinkDemand for Infrastructure permission on the CallContext.GetProperties 
method.

Modified:
    logging/log4net/trunk/src/LogicalThreadContext.cs
    logging/log4net/trunk/src/Util/LogicalThreadContextProperties.cs

Modified: logging/log4net/trunk/src/LogicalThreadContext.cs
URL: 
http://svn.apache.org/viewvc/logging/log4net/trunk/src/LogicalThreadContext.cs?rev=420499&r1=420498&r2=420499&view=diff
==============================================================================
--- logging/log4net/trunk/src/LogicalThreadContext.cs (original)
+++ logging/log4net/trunk/src/LogicalThreadContext.cs Mon Jul 10 04:46:26 2006
@@ -51,6 +51,13 @@
        /// <para>
        /// The Logical Thread Context is managed on a per <see 
cref="System.Runtime.Remoting.Messaging.CallContext"/> basis.
        /// </para>
+       /// <para>
+       /// The <see cref="System.Runtime.Remoting.Messaging.CallContext"/> 
requires a link time 
+       /// <see cref="System.Security.Permissions.SecurityPermission"/> for the
+       /// <see 
cref="System.Security.Permissions.SecurityPermissionFlag.Infrastructure"/>.
+       /// If the calling code does not have this permission then this context 
will be disabled.
+       /// It will not store any property values set on it.
+       /// </para>
        /// </remarks>
        /// <example>Example of using the thread context properties to store a 
username.
        /// <code lang="C#">

Modified: logging/log4net/trunk/src/Util/LogicalThreadContextProperties.cs
URL: 
http://svn.apache.org/viewvc/logging/log4net/trunk/src/Util/LogicalThreadContextProperties.cs?rev=420499&r1=420498&r2=420499&view=diff
==============================================================================
--- logging/log4net/trunk/src/Util/LogicalThreadContextProperties.cs (original)
+++ logging/log4net/trunk/src/Util/LogicalThreadContextProperties.cs Mon Jul 10 
04:46:26 2006
@@ -19,10 +19,8 @@
 // .NET Compact Framework 1.0 has no support for 
System.Runtime.Remoting.Messaging.CallContext
 #if !NETCF
 
-using System;
-using System.Collections;
-
 using System.Runtime.Remoting.Messaging;
+using System.Security;
 
 namespace log4net.Util
 {
@@ -34,10 +32,28 @@
        /// Class implements a collection of properties that is specific to 
each thread.
        /// The class is not synchronized as each thread has its own <see 
cref="PropertiesDictionary"/>.
        /// </para>
+       /// <para>
+       /// This class stores its properties in a slot on the <see 
cref="CallContext"/> named
+       /// <c>log4net.Util.LogicalThreadContextProperties</c>.
+       /// </para>
+       /// <para>
+       /// The <see cref="CallContext"/> requires a link time 
+       /// <see cref="System.Security.Permissions.SecurityPermission"/> for the
+       /// <see 
cref="System.Security.Permissions.SecurityPermissionFlag.Infrastructure"/>.
+       /// If the calling code does not have this permission then this context 
will be disabled.
+       /// It will not store any property values set on it.
+       /// </para>
        /// </remarks>
        /// <author>Nicko Cadell</author>
        public sealed class LogicalThreadContextProperties : 
ContextPropertiesBase
        {
+               private const string c_SlotName = 
"log4net.Util.LogicalThreadContextProperties";
+               
+               /// <summary>
+               /// Flag used to disable this context if we don't have 
permission to access the CallContext.
+               /// </summary>
+               private bool m_disabled = false;
+               
                #region Public Instance Constructors
 
                /// <summary>
@@ -143,16 +159,64 @@
                /// </remarks>
                internal PropertiesDictionary GetProperties(bool create)
                {
-                       PropertiesDictionary properties = 
(PropertiesDictionary)CallContext.GetData("log4net.Util.LogicalThreadContextProperties");
-                       if (properties == null && create)
+                       if (!m_disabled)
                        {
-                               properties  = new PropertiesDictionary();
-                               
CallContext.SetData("log4net.Util.LogicalThreadContextProperties", properties);
+                               try
+                               {
+                                       PropertiesDictionary properties = 
GetCallContextData();
+                                       if (properties == null && create)
+                                       {
+                                               properties = new 
PropertiesDictionary();
+                                               SetCallContextData(properties);
+                                       }
+                                       return properties;
+                               }
+                               catch (SecurityException secEx)
+                               {
+                                       m_disabled = true;
+                                       
+                                       // Thrown if we don't have permission 
to read or write the CallContext
+                                       LogLog.Warn("SecurityException while 
accessing CallContext. Disabling LogicalThreadContextProperties", secEx);
+                               }
                        }
-                       return properties;
+                       
+                       // Only get here is we are disabled because of a 
security exception
+                       if (create)
+                       {
+                               return new PropertiesDictionary();
+                       }
+                       return null;
                }
 
                #endregion Internal Instance Methods
+
+               /// <summary>
+               /// Gets the call context get data.
+               /// </summary>
+               /// <returns>The peroperties dictionary stored in the call 
context</returns>
+               /// <remarks>
+               /// The <see cref="CallContext"/> method <see 
cref="CallContext.GetData"/> has a
+               /// security link demand, therfore we must put the method call 
in a seperate method
+               /// that we can wrap in an exception handler.
+               /// </remarks>
+               private static PropertiesDictionary GetCallContextData()
+               {
+                       return CallContext.GetData(c_SlotName) as 
PropertiesDictionary;
+               }
+
+               /// <summary>
+               /// Sets the call context data.
+               /// </summary>
+               /// <param name="properties">The properties.</param>
+               /// <remarks>
+               /// The <see cref="CallContext"/> method <see 
cref="CallContext.SetData"/> has a
+               /// security link demand, therfore we must put the method call 
in a seperate method
+               /// that we can wrap in an exception handler.
+               /// </remarks>
+               private static void SetCallContextData(PropertiesDictionary 
properties)
+               {
+                       CallContext.SetData(c_SlotName, properties);
+               }
        }
 }
 


Reply via email to