Sanitize Tags Unicode Block (#3920)

This commit is contained in:
Amed Rodriguez
2025-08-08 09:06:08 -07:00
committed by GitHub
parent 5bdbbd0305
commit 48c9af0ed9
3 changed files with 59 additions and 1 deletions
Generated
+10
View File
@@ -3343,6 +3343,7 @@ dependencies = [
"tracing",
"tracing-opentelemetry",
"tracing-subscriber",
"unicode-normalization",
"url",
"urlencoding",
"utoipa",
@@ -8856,6 +8857,15 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
[[package]]
name = "unicode-normalization"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.12.0"
+1
View File
@@ -95,6 +95,7 @@ tempfile = "3.15.0"
dashmap = "6.1"
ahash = "0.8"
tokio-util = "0.7.15"
unicode-normalization = "0.1"
# Vector database for tool selection
lancedb = "0.13"
+48 -1
View File
@@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashSet;
use std::fmt;
use unicode_normalization::UnicodeNormalization;
use utoipa::ToSchema;
use crate::conversation::tool_result_serde;
@@ -409,9 +410,27 @@ impl Message {
self
}
fn sanitize_unicode_tags(text: &str) -> String {
let normalized: String = text.nfc().collect();
// Remove Unicode Tags Block characters only
normalized
.chars()
.filter(|&c| !matches!(c, '\u{E0000}'..='\u{E007F}'))
.collect()
}
/// Add text content to the message
pub fn with_text<S: Into<String>>(self, text: S) -> Self {
self.with_content(MessageContent::text(text))
let raw_text = text.into();
let sanitized_text = Self::sanitize_unicode_tags(&raw_text);
self.with_content(MessageContent::Text(
RawTextContent {
text: sanitized_text,
}
.no_annotation(),
))
}
/// Add image content to the message
@@ -565,6 +584,34 @@ mod tests {
};
use serde_json::{json, Value};
#[test]
fn test_sanitize_unicode_tags() {
let malicious = "Hello\u{E0041}\u{E0042}\u{E0043}world"; // Invisible "ABC"
let cleaned = Message::sanitize_unicode_tags(malicious);
assert_eq!(cleaned, "Helloworld");
}
#[test]
fn test_no_sanitize_unicode_tags() {
let clean_text = "Hello world 世界 🌍";
let cleaned = Message::sanitize_unicode_tags(clean_text);
assert_eq!(cleaned, clean_text);
}
#[test]
fn test_sanitize_with_text() {
let malicious = "Hello\u{E0041}\u{E0042}\u{E0043}world"; // Invisible "ABC"
let message = Message::user().with_text(malicious);
assert_eq!(message.as_concat_text(), "Helloworld");
}
#[test]
fn test_no_sanitize_with_text() {
let clean_text = "Hello world 世界 🌍";
let message = Message::user().with_text(clean_text);
assert_eq!(message.as_concat_text(), clean_text);
}
#[test]
fn test_message_serialization() {
let message = Message::assistant()