This commit is contained in:
Timothy Jaeryang Baek
2026-04-24 18:38:57 +09:00
parent 3560d2f630
commit f48b8ffbf0
3 changed files with 67 additions and 9 deletions
+28 -4
View File
@@ -597,6 +597,9 @@ def sanitize_text_for_db(text: str) -> str:
"""Remove null bytes and invalid UTF-8 surrogates from text for PostgreSQL storage."""
if not isinstance(text, str):
return text
# Fast path: skip work when there are no null bytes (the common case)
if '\x00' not in text:
return text
# Remove null bytes
text = text.replace('\x00', '').replace('\u0000', '')
# Remove invalid UTF-8 surrogate characters that can cause encoding errors
@@ -608,17 +611,38 @@ def sanitize_text_for_db(text: str) -> str:
return text
def sanitize_data_for_db(obj):
"""Recursively sanitize all strings in a data structure for database storage."""
def _strip_null_bytes_deep(obj):
"""Inner recursive walk — only called when null bytes are known to be present."""
if isinstance(obj, str):
return sanitize_text_for_db(obj)
elif isinstance(obj, dict):
return {k: sanitize_data_for_db(v) for k, v in obj.items()}
return {k: _strip_null_bytes_deep(v) for k, v in obj.items()}
elif isinstance(obj, list):
return [sanitize_data_for_db(v) for v in obj]
return [_strip_null_bytes_deep(v) for v in obj]
return obj
def sanitize_data_for_db(obj):
"""Recursively sanitize all strings in a data structure for database storage.
Performs a fast pre-check: serializes the structure once and scans for
null bytes. If none are found (the overwhelmingly common case), the
original object is returned immediately, skipping the expensive
recursive walk.
"""
if isinstance(obj, str):
return sanitize_text_for_db(obj)
# Fast path: check for null bytes in the serialized form.
# json.dumps is implemented in C and much faster than a Python-level
# recursive walk over every leaf string.
try:
if '\x00' not in json.dumps(obj, ensure_ascii=False):
return obj
except (TypeError, ValueError):
pass
return _strip_null_bytes_deep(obj)
def sanitize_metadata(metadata: dict) -> dict:
"""
Return a JSON-safe copy of a metadata dict for database storage.