Bug 1839396 part 17 - Make QuoteString and JSONQuoteString infallible. r=mgaudet

The previous patch reimplemented QuoteString to use a `StringSegmentRange`,
which should avoid mutating the inner parts of `JSRope`, while remaining fast on
`JSAtom`-s.

As the StringSegmentRange does not need to allocate with `ensureLinear`, then
all the failures are reported by the `put` functions using the `GenericPrinter`
mechanism, and the `release` functions of `Sprinter` would report the failure if
any.

Thus, there is no need for retuning a boolean value anymore from `QuoteString`
and `JSONQuoteString`, while this is still necessary to check the returned value
variant of `QuoteString` which returns `UniqueChars` by using the `release`
function of `Sprinter`.

Differential Revision: https://phabricator.services.mozilla.com/D183759
This commit is contained in:
Nicolas B. Pierron 2023-10-04 15:18:20 +00:00
Родитель 580dad9063
Коммит 74af1d594a
5 изменённых файлов: 16 добавлений и 28 удалений

Просмотреть файл

@ -333,18 +333,18 @@ extern JS_PUBLIC_API JS::UniqueChars QuoteString(JSContext* cx, JSString* str,
// Appends the quoted string to the given Sprinter. Follows the same semantics
// as QuoteString from above.
extern JS_PUBLIC_API bool QuoteString(Sprinter* sp, JSString* str,
extern JS_PUBLIC_API void QuoteString(Sprinter* sp, JSString* str,
char quote = '\0');
// Appends the quoted string to the given Sprinter. Follows the same
// Appends the JSON quoted string to the given Sprinter.
extern JS_PUBLIC_API bool JSONQuoteString(Sprinter* sp, JSString* str);
extern JS_PUBLIC_API void JSONQuoteString(Sprinter* sp, JSString* str);
// Internal implementation code for QuoteString methods above.
enum class QuoteTarget { String, JSON };
template <QuoteTarget target, typename CharT>
bool JS_PUBLIC_API QuoteString(Sprinter* sp,
void JS_PUBLIC_API QuoteString(Sprinter* sp,
const mozilla::Range<const CharT> chars,
char quote = '\0');

Просмотреть файл

@ -137,9 +137,7 @@ static JS::UniqueChars QuoteString(JSContext* cx, const char* str) {
}
mozilla::Range range(reinterpret_cast<const Latin1Char*>(str),
std::strlen(str));
if (!QuoteString<QuoteTarget::String>(&sprinter, range)) {
return nullptr;
}
QuoteString<QuoteTarget::String>(&sprinter, range);
return sprinter.release();
}

Просмотреть файл

@ -1004,9 +1004,7 @@ UniqueChars ToPrintableStringImpl(mozilla::Range<CharT> str,
if (!sprinter.init()) {
return nullptr;
}
if (!QuoteString<QuoteTarget::String>(&sprinter, str, quote)) {
return nullptr;
}
QuoteString<QuoteTarget::String>(&sprinter, str, quote);
return sprinter.release();
}

Просмотреть файл

@ -2183,7 +2183,8 @@ bool ExpressionDecompiler::write(JSString* str) {
}
bool ExpressionDecompiler::quote(JSString* s, char quote) {
return QuoteString(&sprinter, s, quote);
QuoteString(&sprinter, s, quote);
return true;
}
JSAtom* ExpressionDecompiler::loadAtom(jsbytecode* pc) {
@ -2605,9 +2606,7 @@ size_t JS::GetPCCountScriptCount(JSContext* cx) {
[[nodiscard]] static bool JSONStringProperty(Sprinter& sp, JSONPrinter& json,
const char* name, JSString* str) {
json.beginStringProperty(name);
if (!JSONQuoteString(&sp, str)) {
return false;
}
JSONQuoteString(&sp, str);
json.endStringProperty();
return true;
}

Просмотреть файл

@ -349,7 +349,7 @@ static const char JSONEscapeMap[] = {
};
template <QuoteTarget target, typename CharT>
JS_PUBLIC_API bool QuoteString(Sprinter* sp,
JS_PUBLIC_API void QuoteString(Sprinter* sp,
const mozilla::Range<const CharT> chars,
char quote) {
MOZ_ASSERT_IF(target == QuoteTarget::JSON, quote == '\0');
@ -370,23 +370,21 @@ JS_PUBLIC_API bool QuoteString(Sprinter* sp,
if (quote) {
sp->putChar(quote);
}
return true;
}
template JS_PUBLIC_API bool QuoteString<QuoteTarget::String, Latin1Char>(
template JS_PUBLIC_API void QuoteString<QuoteTarget::String, Latin1Char>(
Sprinter* sp, const mozilla::Range<const Latin1Char> chars, char quote);
template JS_PUBLIC_API bool QuoteString<QuoteTarget::String, char16_t>(
template JS_PUBLIC_API void QuoteString<QuoteTarget::String, char16_t>(
Sprinter* sp, const mozilla::Range<const char16_t> chars, char quote);
template JS_PUBLIC_API bool QuoteString<QuoteTarget::JSON, Latin1Char>(
template JS_PUBLIC_API void QuoteString<QuoteTarget::JSON, Latin1Char>(
Sprinter* sp, const mozilla::Range<const Latin1Char> chars, char quote);
template JS_PUBLIC_API bool QuoteString<QuoteTarget::JSON, char16_t>(
template JS_PUBLIC_API void QuoteString<QuoteTarget::JSON, char16_t>(
Sprinter* sp, const mozilla::Range<const char16_t> chars, char quote);
JS_PUBLIC_API bool QuoteString(Sprinter* sp, JSString* str,
JS_PUBLIC_API void QuoteString(Sprinter* sp, JSString* str,
char quote /*= '\0' */) {
MOZ_ASSERT(sp->maybeCx);
if (quote) {
@ -398,8 +396,6 @@ JS_PUBLIC_API bool QuoteString(Sprinter* sp, JSString* str,
if (quote) {
sp->putChar(quote);
}
return true;
}
JS_PUBLIC_API UniqueChars QuoteString(JSContext* cx, JSString* str,
@ -408,18 +404,15 @@ JS_PUBLIC_API UniqueChars QuoteString(JSContext* cx, JSString* str,
if (!sprinter.init()) {
return nullptr;
}
if (!QuoteString(&sprinter, str, quote)) {
return nullptr;
}
QuoteString(&sprinter, str, quote);
return sprinter.release();
}
JS_PUBLIC_API bool JSONQuoteString(Sprinter* sp, JSString* str) {
JS_PUBLIC_API void JSONQuoteString(Sprinter* sp, JSString* str) {
MOZ_ASSERT(sp->maybeCx);
JSONEscape esc;
EscapePrinter ep(*sp, esc);
ep.putString(sp->maybeCx, str);
return true;
}
Fprinter::Fprinter(FILE* fp) : file_(nullptr), init_(false) { init(fp); }