From fef2b8ce3bfb25d6a9fdc02e4694cb1bc5bea5cf Mon Sep 17 00:00:00 2001 From: Widthdom Date: Sat, 6 Jun 2026 00:45:42 +0900 Subject: [PATCH 1/3] Add valid MCP audit request id truncation test (#3306) --- tests/CodeIndex.Tests/McpAuditLogTests.cs | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/CodeIndex.Tests/McpAuditLogTests.cs b/tests/CodeIndex.Tests/McpAuditLogTests.cs index 507161074c..79821cf648 100644 --- a/tests/CodeIndex.Tests/McpAuditLogTests.cs +++ b/tests/CodeIndex.Tests/McpAuditLogTests.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.Text; using System.Text.Json; using System.Text.Json.Nodes; using CodeIndex.Cli; @@ -492,6 +493,39 @@ public void ToolsCall_MaxLengthRequestId_PreservesAuditRequestId_Issue3237() Assert.False(record.TryGetProperty("request_id_truncated", out _)); } + [Fact] + public void ToolsCall_EscapedRequestId_TruncatesAuditRequestId_Issue3306() + { + using var sink = new AuditLogSink(_auditPath, AuditLogSink.DefaultMaxBytes, includeValues: false); + using var server = CreateServer(sink); + var id = new string('\u3042', 43); + Assert.True(id.Length <= McpServer.MaxRequestIdCharacterCount); + Assert.True(Encoding.UTF8.GetByteCount(id) <= McpServer.MaxRequestIdByteLength); + var serializedId = JsonSerializer.Serialize(id); + Assert.True(serializedId.Length > AuditLogSink.MaxRequestIdChars); + var requestIdDisplay = McpBoundedText.ForDisplay(serializedId, AuditLogSink.MaxRequestIdChars); + var request = new JsonObject + { + ["jsonrpc"] = "2.0", + ["id"] = id, + ["method"] = "tools/call", + ["params"] = new JsonObject + { + ["name"] = "ping", + ["arguments"] = new JsonObject(), + }, + }; + + var response = server.HandleMessage(request)!; + + Assert.False(response.AsObject().ContainsKey("error")); + Assert.NotNull(response["result"]); + var record = ReadOnlyRecord(); + Assert.Equal(requestIdDisplay.Text, record.GetProperty("request_id").GetString()); + Assert.Equal(serializedId.Length, record.GetProperty("request_id_length").GetInt32()); + Assert.True(record.GetProperty("request_id_truncated").GetBoolean()); + } + [Fact] public void ToolsCall_ValuesOmitted_ByDefault() { From b1d6f9cb371cfe757fc3260881c852449ab3497c Mon Sep 17 00:00:00 2001 From: Widthdom Date: Sat, 6 Jun 2026 00:47:06 +0900 Subject: [PATCH 2/3] Clarify MCP audit request id boundary (#3307) --- tests/CodeIndex.Tests/McpAuditLogTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/CodeIndex.Tests/McpAuditLogTests.cs b/tests/CodeIndex.Tests/McpAuditLogTests.cs index 79821cf648..4430f55ca5 100644 --- a/tests/CodeIndex.Tests/McpAuditLogTests.cs +++ b/tests/CodeIndex.Tests/McpAuditLogTests.cs @@ -463,12 +463,13 @@ public void ToolsCall_CapsAuditArgumentKeyCount_Issue3237() } [Fact] - public void ToolsCall_MaxLengthRequestId_PreservesAuditRequestId_Issue3237() + public void ToolsCall_MaxLengthRequestId_PreservesAuditRequestId_Issue3237_3307() { using var sink = new AuditLogSink(_auditPath, AuditLogSink.DefaultMaxBytes, includeValues: false); using var server = CreateServer(sink); var id = new string('r', McpServer.MaxRequestIdCharacterCount); var serializedId = JsonSerializer.Serialize(id); + Assert.True(serializedId.Length <= AuditLogSink.MaxRequestIdChars); var request = new JsonObject { ["jsonrpc"] = "2.0", From cd13da6ab4260c9a0ed5f9af65d258e883faeb18 Mon Sep 17 00:00:00 2001 From: Widthdom Date: Sat, 6 Jun 2026 00:48:25 +0900 Subject: [PATCH 3/3] Document MCP audit request id cap coverage (#3308) --- changelog.d/unreleased/3306-3308.fixed.md | 17 +++++++++++++++++ tests/CodeIndex.Tests/McpAuditLogTests.cs | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 changelog.d/unreleased/3306-3308.fixed.md diff --git a/changelog.d/unreleased/3306-3308.fixed.md b/changelog.d/unreleased/3306-3308.fixed.md new file mode 100644 index 0000000000..99801f947b --- /dev/null +++ b/changelog.d/unreleased/3306-3308.fixed.md @@ -0,0 +1,17 @@ +--- +category: fixed +issues: + - 3306 + - 3307 + - 3308 +affected: + - tests/CodeIndex.Tests/McpAuditLogTests.cs +--- + +## English + +- **MCP audit request-id truncation coverage now uses a protocol-valid escaped id (#3306, #3307, #3308)**: the regression test now keeps the JSON-RPC id within request validation limits while still making the serialized audit request id exceed the audit display cap. + +## 日本語 + +- **MCP audit request-id truncation のカバレッジが protocol-valid な escaped id を使うようになりました (#3306, #3307, #3308)**: 回帰テストは JSON-RPC id を request validation の上限内に保ちつつ、serialized audit request id が audit 表示上限を超える入力で検証するようになりました。 diff --git a/tests/CodeIndex.Tests/McpAuditLogTests.cs b/tests/CodeIndex.Tests/McpAuditLogTests.cs index 4430f55ca5..94e0ee9ba9 100644 --- a/tests/CodeIndex.Tests/McpAuditLogTests.cs +++ b/tests/CodeIndex.Tests/McpAuditLogTests.cs @@ -127,7 +127,7 @@ public void ToolsCall_MissingToolName_StillEmitsAuditRecord() } [Fact] - public void ToolsCall_OversizedRequestId_IsRejectedBeforeAuditRecord_Issue3104() + public void ToolsCall_OversizedRequestId_IsRejectedBeforeAuditRecord_Issue3104_3308() { using var sink = new AuditLogSink(_auditPath, AuditLogSink.DefaultMaxBytes, includeValues: false); using var server = CreateServer(sink);