Skip to content

Commit 574a082

Browse files
antonisclaude
andcommitted
fix(core): Sanitize lone surrogates in parameterized (fmt) log bodies
`parameterize`/`fmt` creates a `String` object via `new String()`, so `typeof message` returns `'object'` not `'string'`, bypassing the sanitization. Use `String(message)` to coerce to a primitive before sanitizing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent afbd06e commit 574a082

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

packages/core/src/logs/internal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ export function _INTERNAL_captureLog(
162162
const serializedLog: SerializedLog = {
163163
timestamp,
164164
level,
165-
body: typeof message === 'string' ? _INTERNAL_removeLoneSurrogates(message) : message,
165+
body: _INTERNAL_removeLoneSurrogates(String(message)),
166166
trace_id: traceContext?.trace_id,
167167
severity_number: severityNumber ?? SEVERITY_TEXT_TO_SEVERITY_NUMBER[level],
168168
attributes: sanitizeLogAttributes({

packages/core/test/lib/logs/internal.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,19 @@ describe('_INTERNAL_captureLog', () => {
12801280
expect(logBuffer?.[0]?.body).toBe('bad surrogate \uFFFD here');
12811281
});
12821282

1283+
it('sanitizes lone surrogates in parameterized (fmt) log message body', () => {
1284+
const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableLogs: true });
1285+
const client = new TestClient(options);
1286+
const scope = new Scope();
1287+
scope.setClient(client);
1288+
1289+
const badValue = 'bad\uD800value';
1290+
_INTERNAL_captureLog({ level: 'error', message: fmt`parameterized ${badValue} message` }, scope);
1291+
1292+
const logBuffer = _INTERNAL_getLogBuffer(client);
1293+
expect(logBuffer?.[0]?.body).toBe('parameterized bad\uFFFDvalue message');
1294+
});
1295+
12831296
it('sanitizes lone surrogates in log attribute values', () => {
12841297
const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableLogs: true });
12851298
const client = new TestClient(options);

0 commit comments

Comments
 (0)