Skip to content

Commit

Permalink
[devtools] allow non-coercible objects in formatConsoleArgumentsToSin…
Browse files Browse the repository at this point in the history
…gleString
  • Loading branch information
henryqdineen committed Nov 7, 2024
1 parent e137890 commit b46191e
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
6 changes: 6 additions & 0 deletions packages/react-devtools-shared/src/__tests__/utils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ describe('utils', () => {
'Symbol(abc) 123',
);
});

it('should gracefully handle objects with no prototype', () => {
expect(
formatConsoleArgumentsToSingleString('%o', Object.create(null)),
).toEqual('%o [object Object]');
});
});

describe('formatWithStyles', () => {
Expand Down
19 changes: 16 additions & 3 deletions packages/react-devtools-shared/src/backend/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,19 @@ export function serializeToString(data: any): string {
);
}

function safeToString(val: any): string {
try {
return String(val);
} catch (err) {
if (typeof val === 'object') {
// An object with no prototype and no `[Symbol.toPrimitive]()`, `toString()`, and `valueOf()` methods would throw.
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#string_coercion
return '[object Object]';
}
throw err;
}
}

// based on https://github.com/tmpfs/format-util/blob/0e62d430efb0a1c51448709abd3e2406c14d8401/format.js#L1
// based on https://developer.mozilla.org/en-US/docs/Web/API/console#Using_string_substitutions
// Implements s, d, i and f placeholders
Expand All @@ -176,7 +189,7 @@ export function formatConsoleArgumentsToSingleString(
): string {
const args = inputArgs.slice();

let formatted: string = String(maybeMessage);
let formatted: string = safeToString(maybeMessage);

// If the first argument is a string, check for substitutions.
if (typeof maybeMessage === 'string') {
Expand Down Expand Up @@ -211,14 +224,14 @@ export function formatConsoleArgumentsToSingleString(
// Arguments that remain after formatting.
if (args.length) {
for (let i = 0; i < args.length; i++) {
formatted += ' ' + String(args[i]);
formatted += ' ' + safeToString(args[i]);
}
}

// Update escaped %% values.
formatted = formatted.replace(/%{2,2}/g, '%');

Check failure on line 232 in packages/react-devtools-shared/src/backend/utils/index.js

View workflow job for this annotation

GitHub Actions / Run eslint

'formatted' is assigned a value but never used

return String(formatted);
return String();
}

export function isSynchronousXHRSupported(): boolean {
Expand Down

0 comments on commit b46191e

Please sign in to comment.