Skip to content

Commit

Permalink
Cherry-pick 271458@main (d1f1209). https://bugs.webkit.org/show_bug.c…
Browse files Browse the repository at this point in the history
…gi?id=265775

    Gracefully handle OOM while trying to describing a Symbol when creating an Error.
    https://bugs.webkit.org/show_bug.cgi?id=265775
    rdar://119046215

    Reviewed by Yusuke Suzuki.

    If trying to describe a Symbol via stringifying it results in an OutOfMemoryError,
    just simply describe is as a generic "Symbol" instead.

    * JSTests/stress/out-of-memory-while-describing-symbol-for-error.js: Added.
    (catch):
    * Source/JavaScriptCore/runtime/ExceptionHelpers.cpp:
    (JSC::errorDescriptionForValue):
    * Source/JavaScriptCore/runtime/Symbol.cpp:
    (JSC::Symbol::tryGetDescriptiveString const):
    * Source/JavaScriptCore/runtime/Symbol.h:

    Canonical link: https://commits.webkit.org/271458@main
  • Loading branch information
Mark Lam authored and aperezdc committed Jan 26, 2024
1 parent 92db624 commit 0a74b85
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 5 deletions.
14 changes: 14 additions & 0 deletions JSTests/stress/out-of-memory-while-describing-symbol-for-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//@ skip if $memoryLimited

let a = "?".repeat(2147483647);
var exception;
try {
var s = Symbol(a);
new s(2);
} catch (e) {
exception = e;
}

if (exception != "TypeError: Symbol is not a constructor (evaluating 'new s(2)')")
throw "FAILED";

11 changes: 8 additions & 3 deletions Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2021 Apple Inc. All rights reserved.
* Copyright (C) 2008-2023 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
Expand Down Expand Up @@ -62,8 +62,13 @@ String errorDescriptionForValue(JSGlobalObject* globalObject, JSValue v)
return tryMakeString('"', string, '"');
}

if (v.isSymbol())
return asSymbol(v)->descriptiveString();
if (v.isSymbol()) {
auto expectedDescription = asSymbol(v)->tryGetDescriptiveString();
if (expectedDescription)
return expectedDescription.value();
ASSERT(expectedDescription.error() == ErrorTypeWithExtension::OutOfMemoryError);
return String("Symbol"_s);
}
if (v.isObject()) {
VM& vm = globalObject->vm();
JSObject* object = asObject(v);
Expand Down
10 changes: 9 additions & 1 deletion Source/JavaScriptCore/runtime/Symbol.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2022 Apple Inc. All rights reserved.
* Copyright (C) 2012-2023 Apple Inc. All rights reserved.
* Copyright (C) 2015-2016 Yusuke Suzuki <utatane.tea@gmail.com>.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -88,6 +88,14 @@ String Symbol::descriptiveString() const
return makeString("Symbol("_s, StringView(m_privateName.uid()), ')');
}

Expected<String, ErrorTypeWithExtension> Symbol::tryGetDescriptiveString() const
{
String description = tryMakeString("Symbol("_s, StringView(m_privateName.uid()), ')');
if (!description)
return makeUnexpected(ErrorTypeWithExtension::OutOfMemoryError);
return description;
}

String Symbol::description() const
{
auto& uid = m_privateName.uid();
Expand Down
5 changes: 4 additions & 1 deletion Source/JavaScriptCore/runtime/Symbol.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2022 Apple Inc. All rights reserved.
* Copyright (C) 2012-2023 Apple Inc. All rights reserved.
* Copyright (C) 2015-2016 Yusuke Suzuki <utatane.tea@gmail.com>.
*
* Redistribution and use in source and binary forms, with or without
Expand All @@ -26,8 +26,10 @@

#pragma once

#include "ErrorType.h"
#include "JSString.h"
#include "PrivateName.h"
#include <wtf/Expected.h>

namespace JSC {

Expand Down Expand Up @@ -59,6 +61,7 @@ class Symbol final : public JSCell {
PrivateName privateName() const { return m_privateName; }
String descriptiveString() const;
String description() const;
Expected<String, ErrorTypeWithExtension> tryGetDescriptiveString() const;

JSValue toPrimitive(JSGlobalObject*, PreferredPrimitiveType) const;
JSObject* toObject(JSGlobalObject*) const;
Expand Down

0 comments on commit 0a74b85

Please sign in to comment.