File: 07-CVE-2025-54813-Escape-control-characters-in-JSONLayout.patch

package info (click to toggle)
log4cxx 1.4.0-1%2Bdeb13u1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 5,636 kB
  • sloc: cpp: 47,740; xml: 1,041; sh: 43; makefile: 17
file content (121 lines) | stat: -rw-r--r-- 3,586 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
Description: CVE-2025-54813 - Improper escaping with JSONLayout
Origin: https://github.com/apache/logging-log4cxx/commit/a799c934545311ff4179c68e16bbeb02b5c66348
Bug: https://logging.apache.org/security.html#CVE-2025-54813
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1111881

From a799c934545311ff4179c68e16bbeb02b5c66348 Mon Sep 17 00:00:00 2001
From: Stephen Webb <stephen.webb@ieee.org>
Date: Tue, 22 Jul 2025 11:32:03 +1000
Subject: [PATCH] Escape control characters in JSONLayout data (#512)

---
 src/main/cpp/jsonlayout.cpp     | 52 +++++++++++++++------------------
 src/test/cpp/jsonlayouttest.cpp | 14 +++++++++
 2 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/src/main/cpp/jsonlayout.cpp b/src/main/cpp/jsonlayout.cpp
index d8d062d79..3e0abf486 100644
--- a/src/main/cpp/jsonlayout.cpp
+++ b/src/main/cpp/jsonlayout.cpp
@@ -215,32 +215,31 @@ void JSONLayout::appendQuotedEscapedString(LogString& buf,
 
 void JSONLayout::appendItem(const LogString& input, LogString& buf)
 {
-	/* add leading quote */
-	buf.push_back(0x22);
-
-	logchar specialChars[] =
+	auto toHexDigit = [](int ch) -> int
 	{
-		0x08,   /* \b backspace         */
-		0x09,   /* \t tab               */
-		0x0a,   /* \n newline           */
-		0x0c,   /* \f form feed         */
-		0x0d,   /* \r carriage return   */
-		0x22,   /* \" double quote      */
-		0x5c,   /* \\ backslash         */
-		0x00    /* terminating NULL for C-strings */
+		return (10 <= ch ? (0x61 - 10) : 0x30) + ch;
 	};
+	/* add leading quote */
+	buf.push_back(0x22);
 
 	size_t start = 0;
-	size_t found = input.find_first_of(specialChars, start);
+	size_t index = 0;
 
-	while (found != LogString::npos)
+	for (int ch : input)
 	{
-		if (found > start)
+		if (0x22 == ch || 0x5c == ch)
+			;
+		else if (0x20 <= ch)
+		{
+			++index;
+			continue;
+		}
+		if (start < index)
 		{
-			buf.append(input, start, found - start);
+			buf.append(input, start, index - start);
 		}
 
-		switch (input[found])
+		switch (ch)
 		{
 			case 0x08:
 				/* \b backspace */
@@ -285,20 +284,15 @@ void JSONLayout::appendItem(const LogString& input, LogString& buf)
 				break;
 
 			default:
-				buf.push_back(input[found]);
+				buf.push_back(0x5c);
+				buf.push_back(0x75); // 'u'
+				buf.push_back(toHexDigit((ch & 0xF000) >> 12));
+				buf.push_back(toHexDigit((ch & 0xF00) >> 8));
+				buf.push_back(toHexDigit((ch & 0xF0) >> 4));
+				buf.push_back(toHexDigit(ch & 0xF));
 				break;
 		}
-
-		start = found + 1;
-
-		if (found < input.size())
-		{
-			found = input.find_first_of(specialChars, start);
-		}
-		else
-		{
-			found = LogString::npos;
-		}
+		start = ++index;
 	}
 
 	if (start < input.size())
diff --git a/src/test/cpp/jsonlayouttest.cpp b/src/test/cpp/jsonlayouttest.cpp
index fda39fca2..75f17dc0a 100644
--- a/src/test/cpp/jsonlayouttest.cpp
+++ b/src/test/cpp/jsonlayouttest.cpp
@@ -163,6 +163,20 @@ LOGUNIT_CLASS(JSONLayoutTest), public JSONLayout
 
 		appendQuotedEscapedString(cr_escaped, cr);
 		LOGUNIT_ASSERT_EQUAL(cr_expected, cr_escaped);
+
+		logchar sub[] = {0x1a, 0x00};
+		logchar sub_expected[] = {0x22, 0x5c, 'u', 0x30, 0x30, 0x31, 0x61, 0x22, 0x00};      /* SUB */
+		LogString sub_escaped;
+
+		appendQuotedEscapedString(sub_escaped, sub);
+		LOGUNIT_ASSERT_EQUAL(sub_expected, sub_escaped);
+
+		logchar esc[] = {0x1e, 0x00};
+		logchar esc_expected[] = {0x22, 0x5c, 'u', 0x30, 0x30, 0x31, 0x65, 0x22, 0x00};      /* ESC */
+		LogString esc_escaped;
+
+		appendQuotedEscapedString(esc_escaped, esc);
+		LOGUNIT_ASSERT_EQUAL(esc_expected, esc_escaped);
 	}
 
 	/**