You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by bo...@apache.org on 2011/09/13 12:14:43 UTC
svn commit: r1170104 - in /logging/log4net/trunk:
src/Layout/Pattern/NamedPatternConverter.cs
tests/src/Layout/PatternLayoutTest.cs
Author: bodewig
Date: Tue Sep 13 10:14:42 2011
New Revision: 1170104
URL: http://svn.apache.org/viewvc?rev=1170104&view=rev
Log:
fix bounds-checks in NamedPatternConverter. LOG4NET-215
Modified:
logging/log4net/trunk/src/Layout/Pattern/NamedPatternConverter.cs
logging/log4net/trunk/tests/src/Layout/PatternLayoutTest.cs
Modified: logging/log4net/trunk/src/Layout/Pattern/NamedPatternConverter.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Layout/Pattern/NamedPatternConverter.cs?rev=1170104&r1=1170103&r2=1170104&view=diff
==============================================================================
--- logging/log4net/trunk/src/Layout/Pattern/NamedPatternConverter.cs (original)
+++ logging/log4net/trunk/src/Layout/Pattern/NamedPatternConverter.cs Tue Sep 13 10:14:42 2011
@@ -42,9 +42,9 @@ namespace log4net.Layout.Pattern
/// </para>
/// </remarks>
/// <author>Nicko Cadell</author>
- internal abstract class NamedPatternConverter : PatternLayoutConverter, IOptionHandler
+ public abstract class NamedPatternConverter : PatternLayoutConverter, IOptionHandler
{
- protected int m_precision = 0;
+ private int m_precision = 0;
#region Implementation of IOptionHandler
@@ -120,31 +120,37 @@ namespace log4net.Layout.Pattern
/// Render the <see cref="GetFullyQualifiedName"/> to the precision
/// specified by the <see cref="PatternConverter.Option"/> property.
/// </remarks>
- override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
+ sealed override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
string name = GetFullyQualifiedName(loggingEvent);
- if (m_precision <= 0)
+ if (m_precision <= 0 || name == null || name.Length < 2)
{
writer.Write(name);
}
else
{
int len = name.Length;
+ string trailingDot = string.Empty;
+ if (name.EndsWith(DOT))
+ {
+ trailingDot = DOT;
+ name = name.Substring(0, len - 1);
+ len--;
+ }
- // We subtract 1 from 'len' when assigning to 'end' to avoid out of
- // bounds exception in return name.Substring(end+1, len). This can happen if
- // precision is 1 and the logger name ends with a dot.
- int end = len - 1;
- for(int i=m_precision; i>0; i--)
- {
- end = name.LastIndexOf('.', end-1);
- if (end == -1)
- {
- writer.Write(name);
- return;
- }
- }
- writer.Write(name.Substring(end+1, len-end-1));
+ int end = name.LastIndexOf(DOT);
+ for(int i = 1; end > 0 && i < m_precision; i++)
+ {
+ end = name.LastIndexOf('.', end - 1);
+ }
+ if (end == -1)
+ {
+ writer.Write(name + trailingDot);
+ }
+ else
+ {
+ writer.Write(name.Substring(end + 1, len - end - 1) + trailingDot);
+ }
}
}
@@ -159,6 +165,7 @@ namespace log4net.Layout.Pattern
/// </remarks>
private readonly static Type declaringType = typeof(NamedPatternConverter);
+ private const string DOT = ".";
#endregion Private Static Fields
}
}
Modified: logging/log4net/trunk/tests/src/Layout/PatternLayoutTest.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/tests/src/Layout/PatternLayoutTest.cs?rev=1170104&r1=1170103&r2=1170104&view=diff
==============================================================================
--- logging/log4net/trunk/tests/src/Layout/PatternLayoutTest.cs (original)
+++ logging/log4net/trunk/tests/src/Layout/PatternLayoutTest.cs Tue Sep 13 10:14:42 2011
@@ -33,10 +33,10 @@ using NUnit.Framework;
namespace log4net.Tests.Layout
{
/// <summary>
- /// Used for internal unit testing the <see cref="PatternLayoutTest"/> class.
+ /// Used for internal unit testing the <see cref="PatternLayout"/> class.
/// </summary>
/// <remarks>
- /// Used for internal unit testing the <see cref="PatternLayoutTest"/> class.
+ /// Used for internal unit testing the <see cref="PatternLayout"/> class.
/// </remarks>
[TestFixture]
public class PatternLayoutTest
@@ -145,7 +145,147 @@ namespace log4net.Tests.Layout
stringAppender.Reset();
}
- /// <summary>
+ [Test]
+ public void NamedPatternConverterWithoutPrecisionShouldReturnFullName()
+ {
+ StringAppender stringAppender = new StringAppender();
+ PatternLayout layout = new PatternLayout();
+ layout.AddConverter("message-as-name", typeof(MessageAsNamePatternConverter));
+ layout.ConversionPattern = "%message-as-name";
+ layout.ActivateOptions();
+ stringAppender.Layout = layout;
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestAddingCustomPattern");
+
+ log1.Info("NoDots");
+ Assert.AreEqual("NoDots", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("One.Dot");
+ Assert.AreEqual("One.Dot", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("Tw.o.Dots");
+ Assert.AreEqual("Tw.o.Dots", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("TrailingDot.");
+ Assert.AreEqual("TrailingDot.", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info(".LeadingDot");
+ Assert.AreEqual(".LeadingDot", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ // empty string and other evil combinations as tests for of-by-one mistakes in index calculations
+ log1.Info(string.Empty);
+ Assert.AreEqual(string.Empty, stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info(".");
+ Assert.AreEqual(".", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("x");
+ Assert.AreEqual("x", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+ }
+
+ [Test]
+ public void NamedPatternConverterWithPrecision1ShouldStripLeadingStuffIfPresent()
+ {
+ StringAppender stringAppender = new StringAppender();
+ PatternLayout layout = new PatternLayout();
+ layout.AddConverter("message-as-name", typeof(MessageAsNamePatternConverter));
+ layout.ConversionPattern = "%message-as-name{1}";
+ layout.ActivateOptions();
+ stringAppender.Layout = layout;
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestAddingCustomPattern");
+
+ log1.Info("NoDots");
+ Assert.AreEqual("NoDots", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("One.Dot");
+ Assert.AreEqual("Dot", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("Tw.o.Dots");
+ Assert.AreEqual("Dots", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("TrailingDot.");
+ Assert.AreEqual("TrailingDot.", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info(".LeadingDot");
+ Assert.AreEqual("LeadingDot", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ // empty string and other evil combinations as tests for of-by-one mistakes in index calculations
+ log1.Info(string.Empty);
+ Assert.AreEqual(string.Empty, stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("x");
+ Assert.AreEqual("x", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info(".");
+ Assert.AreEqual(".", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+ }
+
+ [Test]
+ public void NamedPatternConverterWithPrecision2ShouldStripLessLeadingStuffIfPresent() {
+ StringAppender stringAppender = new StringAppender();
+ PatternLayout layout = new PatternLayout();
+ layout.AddConverter("message-as-name", typeof(MessageAsNamePatternConverter));
+ layout.ConversionPattern = "%message-as-name{2}";
+ layout.ActivateOptions();
+ stringAppender.Layout = layout;
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestAddingCustomPattern");
+
+ log1.Info("NoDots");
+ Assert.AreEqual("NoDots", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("One.Dot");
+ Assert.AreEqual("One.Dot", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("Tw.o.Dots");
+ Assert.AreEqual("o.Dots", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("TrailingDot.");
+ Assert.AreEqual("TrailingDot.", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info(".LeadingDot");
+ Assert.AreEqual("LeadingDot", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ // empty string and other evil combinations as tests for of-by-one mistakes in index calculations
+ log1.Info(string.Empty);
+ Assert.AreEqual(string.Empty, stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info("x");
+ Assert.AreEqual("x", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+
+ log1.Info(".");
+ Assert.AreEqual(".", stringAppender.GetString(), "%message-as-name not registered");
+ stringAppender.Reset();
+ }
+
+ /// <summary>
/// Converter to include event message
/// </summary>
private class TestMessagePatternConverter : PatternLayoutConverter
@@ -181,5 +321,13 @@ namespace log4net.Tests.Layout
stringAppender.Reset();
}
- }
+
+ private class MessageAsNamePatternConverter : NamedPatternConverter
+ {
+ protected override string GetFullyQualifiedName(LoggingEvent loggingEvent)
+ {
+ return loggingEvent.MessageObject.ToString();
+ }
+ }
+ }
}
\ No newline at end of file