diff --git a/Userland/Libraries/LibJS/Print.cpp b/Userland/Libraries/LibJS/Print.cpp index 804fc5c6f1..1666729aae 100644 --- a/Userland/Libraries/LibJS/Print.cpp +++ b/Userland/Libraries/LibJS/Print.cpp @@ -66,6 +66,38 @@ namespace { +static ErrorOr escape_for_string_literal(StringView string) +{ + StringBuilder builder; + for (auto byte : string.bytes()) { + switch (byte) { + case '\r': + TRY(builder.try_append("\\r"sv)); + continue; + case '\v': + TRY(builder.try_append("\\v"sv)); + continue; + case '\f': + TRY(builder.try_append("\\f"sv)); + continue; + case '\b': + TRY(builder.try_append("\\b"sv)); + continue; + case '\n': + TRY(builder.try_append("\\n"sv)); + continue; + case '\\': + TRY(builder.try_append("\\\\"sv)); + continue; + default: + TRY(builder.try_append(byte)); + continue; + } + } + + return builder.to_string(); +} + ErrorOr print_value(JS::PrintContext&, JS::Value value, HashTable& seen_objects); template @@ -1014,11 +1046,18 @@ ErrorOr print_value(JS::PrintContext& print_context, JS::Value value, Hash TRY(js_out(print_context, "\033[33;1m")); else if (value.is_undefined()) TRY(js_out(print_context, "\033[34;1m")); + if (value.is_string()) TRY(js_out(print_context, "\"")); else if (value.is_negative_zero()) TRY(js_out(print_context, "-")); - TRY(js_out(print_context, "{}", TRY(value.to_string_without_side_effects()))); + + auto contents = TRY(value.to_string_without_side_effects()); + if (value.is_string()) + TRY(js_out(print_context, "{}", TRY(escape_for_string_literal(contents)))); + else + TRY(js_out(print_context, "{}", contents)); + if (value.is_string()) TRY(js_out(print_context, "\"")); TRY(js_out(print_context, "\033[0m"));