Skip to content

Commit 900f286

Browse files
committed
escape what RemoteSyslogAppender cannot send instead of deleting it #315
RFC 3164 allows only visible ASCII and space in the message, and everything else fell through the loop unwritten. "Schoenwetter <CJK>" reached the collector as "Schnwetter ", and a tab vanished from between its neighbours, with no marker and no error. Such characters are now written as a \uXXXX escape, which stays inside the allowed range. Encoding still cannot make the message body non-ASCII, which the appender page now says.
1 parent b8d6bf1 commit 900f286

4 files changed

Lines changed: 49 additions & 0 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="https://logging.apache.org/xml/ns"
4+
xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
5+
type="fixed">
6+
<issue id="315" link="https://github.com/apache/logging-log4net/pull/315"/>
7+
<description format="asciidoc">
8+
escape the characters `RemoteSyslogAppender` cannot send instead of deleting them. RFC 3164
9+
allows only the visible ASCII characters and space, and everything else was dropped silently, so
10+
`Sch&#246;nwetter &#20320;&#22909;` reached the collector as `Schnwetter ` and a tab disappeared
11+
from between its neighbours. Such characters are now written as a `\uXXXX` escape, which keeps
12+
the record inside the allowed range and readable (audit da18b6fd-f035)
13+
</description>
14+
</entry>

‎src/log4net.Tests/Appender/RemoteSyslogAppenderTest.cs‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,30 @@ private sealed class RecordingErrorHandler : IErrorHandler
6969

7070
private const int FlushTimeoutMillis = 30_000;
7171

72+
/// <summary>
73+
/// Content outside the RFC 3164 range used to be deleted with no marker, so a message written
74+
/// in a non-Latin script reached the audit trail empty.
75+
/// </summary>
76+
[Test]
77+
public void NonAsciiContentIsEscapedAndNotDeleted()
78+
{
79+
List<byte[]> sentBytes = ExecuteAppend("Sch\u00f6nwetter \u4f60\u597d");
80+
81+
Assert.That(sentBytes, Has.Count.EqualTo(1));
82+
Assert.That(Encoding.ASCII.GetString(sentBytes[0]),
83+
Is.EqualTo(@"<14>TestDomain: INFO - Sch\u00f6nwetter \u4f60\u597d"));
84+
}
85+
86+
/// <summary>A control character other than CR or LF was dropped as well.</summary>
87+
[Test]
88+
public void OtherControlCharactersAreEscaped()
89+
{
90+
List<byte[]> sentBytes = ExecuteAppend("a\tb");
91+
92+
Assert.That(sentBytes, Has.Count.EqualTo(1));
93+
Assert.That(Encoding.ASCII.GetString(sentBytes[0]), Is.EqualTo(@"<14>TestDomain: INFO - a\u0009b"));
94+
}
95+
7296
/// <summary>Bounded, so an unreachable server cannot grow the queue without limit.</summary>
7397
[Test]
7498
public void SendQueueSizeDefaultsTo500()

‎src/log4net/Appender/RemoteSyslogAppender.cs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#endregion
1919

2020
using System;
21+
using System.Globalization;
2122
using System.Text;
2223
using System.Threading;
2324
using log4net.Appender.Internal;
@@ -484,6 +485,12 @@ protected virtual void AppendMessage(string message, ref int characterIndex, Str
484485
break;
485486
}
486487
}
488+
else
489+
{
490+
// Escaped, not dropped: content is masked visibly rather than deleted. RFC 3164 allows
491+
// only 0x20 to 0x7E here, so the escape itself stays inside that range.
492+
builder.Append("\\u").Append(((int)c).ToString("x4", CultureInfo.InvariantCulture));
493+
}
487494
}
488495
}
489496

‎src/site/antora/modules/ROOT/pages/manual/configuration/appenders/remotesyslogappender.adoc‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ You can also specify:
4545
* SendQueueSize (default: 500), how many datagrams may wait to be sent
4646
* EnqueueTimeoutMillis (default: 5000), how long a logging call waits for room in a full queue
4747
48+
RFC 3164 allows only the visible ASCII characters and space in the message, so anything else is
49+
written as a `\uXXXX` escape rather than dropped: a message in a non-Latin script reaches the
50+
collector readable instead of empty. `Encoding` therefore does not make the message body non-ASCII.
51+
4852
Datagrams are handed to a background thread, so a slow or unreachable syslog server does not hold
4953
up logging. Once the queue is full, a logging call waits `EnqueueTimeoutMillis` for room and the
5054
datagram is then discarded and counted, rather than growing the queue without limit. `Flush` waits

0 commit comments

Comments
 (0)