зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 5 changesets (bug 1869726, bug 1874376) for causing build bustages at xpcpublic.h. CLOSED TREE
Backed out changeset 798348b12f54 (bug 1874376) Backed out changeset 4b6d579ac625 (bug 1869726) Backed out changeset 580bab49ba2c (bug 1869726) Backed out changeset d819bf7b53fa (bug 1869726) Backed out changeset 9b061f42271e (bug 1869726)
This commit is contained in:
Родитель
6f8dfdc71f
Коммит
5d6e8d45a5
|
@ -120,11 +120,6 @@ template <typename T, typename std::enable_if_t<std::is_same<
|
|||
inline bool AssignJSString(JSContext* cx, T& dest, JSString* s) {
|
||||
using namespace mozilla;
|
||||
CheckedInt<size_t> bufLen(JS::GetStringLength(s));
|
||||
|
||||
if (XPCStringConvert::MaybeAssignUTF8StringChars(s, bufLen.value(), dest)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// From the contract for JS_EncodeStringToUTF8BufferPartial, to guarantee that
|
||||
// the whole string is converted.
|
||||
if (JS::StringHasLatin1Chars(s)) {
|
||||
|
|
|
@ -2575,7 +2575,13 @@ inline bool ByteStringToJsval(JSContext* cx, const nsACString& str,
|
|||
// TODO(bug 1606957): This could probably be better.
|
||||
inline bool NonVoidUTF8StringToJsval(JSContext* cx, const nsACString& str,
|
||||
JS::MutableHandle<JS::Value> rval) {
|
||||
return xpc::NonVoidUTF8StringToJsval(cx, str, rval);
|
||||
JSString* jsStr =
|
||||
JS_NewStringCopyUTF8N(cx, {str.BeginReading(), str.Length()});
|
||||
if (!jsStr) {
|
||||
return false;
|
||||
}
|
||||
rval.setString(jsStr);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool UTF8StringToJsval(JSContext* cx, const nsACString& str,
|
||||
|
|
|
@ -235,13 +235,81 @@ bool XPCConvert::NativeData2JS(JSContext* cx, MutableHandleValue d,
|
|||
return true;
|
||||
}
|
||||
|
||||
nsStringBuffer* buf;
|
||||
if (!XPCStringConvert::UTF8ToJSVal(cx, *utf8String, &buf, d)) {
|
||||
if (utf8String->IsEmpty()) {
|
||||
d.set(JS_GetEmptyStringValue(cx));
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t len = utf8String->Length();
|
||||
auto allocLen = CheckedUint32(len) + 1;
|
||||
if (!allocLen.isValid()) {
|
||||
return false;
|
||||
}
|
||||
if (buf) {
|
||||
buf->AddRef();
|
||||
|
||||
// Usage of UTF-8 in XPConnect is mostly for things that are
|
||||
// almost always ASCII, so the inexact allocations below
|
||||
// should be fine.
|
||||
|
||||
if (IsUtf8Latin1(*utf8String)) {
|
||||
using UniqueLatin1Chars =
|
||||
js::UniquePtr<JS::Latin1Char[], JS::FreePolicy>;
|
||||
|
||||
UniqueLatin1Chars buffer(static_cast<JS::Latin1Char*>(
|
||||
JS_string_malloc(cx, allocLen.value())));
|
||||
if (!buffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t written = LossyConvertUtf8toLatin1(
|
||||
*utf8String, Span(reinterpret_cast<char*>(buffer.get()), len));
|
||||
buffer[written] = 0;
|
||||
|
||||
// written can never exceed len, so the truncation is OK.
|
||||
JSString* str = JS_NewLatin1String(cx, std::move(buffer), written);
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
|
||||
d.setString(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 1-byte sequences decode to 1 UTF-16 code unit
|
||||
// 2-byte sequences decode to 1 UTF-16 code unit
|
||||
// 3-byte sequences decode to 1 UTF-16 code unit
|
||||
// 4-byte sequences decode to 2 UTF-16 code units
|
||||
// So the number of output code units never exceeds
|
||||
// the number of input code units (but see the comment
|
||||
// below). allocLen already takes the zero terminator
|
||||
// into account.
|
||||
allocLen *= sizeof(char16_t);
|
||||
if (!allocLen.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::UniqueTwoByteChars buffer(
|
||||
static_cast<char16_t*>(JS_string_malloc(cx, allocLen.value())));
|
||||
if (!buffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For its internal simplicity, ConvertUTF8toUTF16 requires the
|
||||
// destination to be one code unit longer than the source, but
|
||||
// it never actually writes more code units than the number of
|
||||
// code units in the source. That's why it's OK to claim the
|
||||
// output buffer has len + 1 space but then still expect to
|
||||
// have space for the zero terminator.
|
||||
size_t written =
|
||||
ConvertUtf8toUtf16(*utf8String, Span(buffer.get(), allocLen.value()));
|
||||
MOZ_RELEASE_ASSERT(written <= len);
|
||||
buffer[written] = 0;
|
||||
|
||||
JSString* str = JS_NewUCStringDontDeflate(cx, std::move(buffer), written);
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
|
||||
d.setString(str);
|
||||
return true;
|
||||
}
|
||||
case nsXPTType::T_CSTRING: {
|
||||
|
@ -590,6 +658,7 @@ bool XPCConvert::JSData2Native(JSContext* cx, void* d, HandleValue s,
|
|||
return true;
|
||||
}
|
||||
|
||||
// The JS val is neither null nor void...
|
||||
JSString* str = ToString(cx, s);
|
||||
if (!str) {
|
||||
return false;
|
||||
|
@ -601,7 +670,24 @@ bool XPCConvert::JSData2Native(JSContext* cx, void* d, HandleValue s,
|
|||
return true;
|
||||
}
|
||||
|
||||
return AssignJSString(cx, *rs, str);
|
||||
JSLinearString* linear = JS_EnsureLinearString(cx, str);
|
||||
if (!linear) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t utf8Length = JS::GetDeflatedUTF8StringLength(linear);
|
||||
if (!rs->SetLength(utf8Length, fallible)) {
|
||||
if (pErr) {
|
||||
*pErr = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
mozilla::DebugOnly<size_t> written = JS::DeflateStringToUTF8Buffer(
|
||||
linear, mozilla::Span(rs->BeginWriting(), utf8Length));
|
||||
MOZ_ASSERT(written == utf8Length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case nsXPTType::T_CSTRING: {
|
||||
|
|
|
@ -158,39 +158,6 @@ bool XPCStringConvert::Latin1ToJSVal(JSContext* cx, const nsACString& latin1,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool XPCStringConvert::UTF8ToJSVal(JSContext* cx, const nsACString& utf8,
|
||||
nsStringBuffer** sharedBuffer,
|
||||
MutableHandleValue vp) {
|
||||
*sharedBuffer = nullptr;
|
||||
|
||||
uint32_t length = utf8.Length();
|
||||
|
||||
if (utf8.IsLiteral()) {
|
||||
return UTF8StringLiteralToJSVal(
|
||||
cx, JS::UTF8Chars(utf8.BeginReading(), length), vp);
|
||||
}
|
||||
|
||||
nsStringBuffer* buf = nsStringBuffer::FromString(utf8);
|
||||
if (buf) {
|
||||
bool shared;
|
||||
if (!UTF8StringBufferToJSVal(cx, buf, length, vp, &shared)) {
|
||||
return false;
|
||||
}
|
||||
if (shared) {
|
||||
*sharedBuffer = buf;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
JSString* str =
|
||||
JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(utf8.BeginReading(), length));
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
vp.setString(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace xpc {
|
||||
|
||||
bool NonVoidStringToJsval(JSContext* cx, nsAString& str,
|
||||
|
@ -251,33 +218,4 @@ bool NonVoidLatin1StringToJsval(JSContext* cx, const nsACString& str,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool NonVoidUTF8StringToJsval(JSContext* cx, nsACString& str,
|
||||
MutableHandleValue rval) {
|
||||
nsStringBuffer* sharedBuffer;
|
||||
if (!XPCStringConvert::UTF8ToJSVal(cx, str, &sharedBuffer, rval)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sharedBuffer) {
|
||||
// The string was shared but UTF8ToJSVal didn't addref it.
|
||||
// Move the ownership from str to jsstr.
|
||||
str.ForgetSharedBuffer();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NonVoidUTF8StringToJsval(JSContext* cx, const nsACString& str,
|
||||
MutableHandleValue rval) {
|
||||
nsStringBuffer* sharedBuffer;
|
||||
if (!XPCStringConvert::UTF8ToJSVal(cx, str, &sharedBuffer, rval)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sharedBuffer) {
|
||||
// The string was shared but UTF8ToJSVal didn't addref it.
|
||||
sharedBuffer->AddRef();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace xpc
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include "ErrorList.h"
|
||||
#include "js/BuildId.h"
|
||||
#include "js/ErrorReport.h"
|
||||
|
@ -26,7 +25,6 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/TextUtils.h"
|
||||
#include "mozilla/dom/DOMString.h"
|
||||
#include "mozilla/fallible.h"
|
||||
#include "nsAtom.h"
|
||||
|
@ -259,9 +257,6 @@ class XPCStringConvert {
|
|||
static bool Latin1ToJSVal(JSContext* cx, const nsACString& latin1,
|
||||
nsStringBuffer** sharedBuffer,
|
||||
JS::MutableHandle<JS::Value> vp);
|
||||
static bool UTF8ToJSVal(JSContext* cx, const nsACString& utf8,
|
||||
nsStringBuffer** sharedBuffer,
|
||||
JS::MutableHandle<JS::Value> vp);
|
||||
|
||||
// Convert the given stringbuffer/length pair to a jsval
|
||||
static MOZ_ALWAYS_INLINE bool UCStringBufferToJSVal(
|
||||
|
@ -290,19 +285,6 @@ class XPCStringConvert {
|
|||
return true;
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool UTF8StringBufferToJSVal(
|
||||
JSContext* cx, nsStringBuffer* buf, uint32_t length,
|
||||
JS::MutableHandle<JS::Value> rval, bool* sharedBuffer) {
|
||||
JSString* str = JS_NewMaybeExternalStringUTF8(
|
||||
cx, {static_cast<const char*>(buf->Data()), length},
|
||||
&sDOMStringExternalString, sharedBuffer);
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
rval.setString(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool StringLiteralToJSVal(JSContext* cx,
|
||||
const char16_t* literal,
|
||||
uint32_t length,
|
||||
|
@ -331,19 +313,6 @@ class XPCStringConvert {
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline bool UTF8StringLiteralToJSVal(
|
||||
JSContext* cx, const JS::UTF8Chars& chars,
|
||||
JS::MutableHandle<JS::Value> rval) {
|
||||
bool ignored;
|
||||
JSString* str = JS_NewMaybeExternalStringUTF8(
|
||||
cx, chars, &sLiteralExternalString, &ignored);
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
rval.setString(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
static MOZ_ALWAYS_INLINE bool MaybeGetExternalStringChars(
|
||||
JSString* str, const JSExternalStringCallbacks** callbacks,
|
||||
|
@ -356,58 +325,30 @@ class XPCStringConvert {
|
|||
return JS::IsExternalStringLatin1(str, callbacks, chars);
|
||||
}
|
||||
|
||||
enum class AcceptedEncoding { All, ASCII };
|
||||
|
||||
template <typename SrcCharT, typename DestCharT, AcceptedEncoding encoding,
|
||||
typename T>
|
||||
template <typename SrcCharT, typename DestCharT, typename T>
|
||||
static MOZ_ALWAYS_INLINE bool MaybeAssignStringChars(JSString* s, size_t len,
|
||||
T& dest) {
|
||||
MOZ_ASSERT(len == JS::GetStringLength(s));
|
||||
static_assert(sizeof(SrcCharT) == sizeof(DestCharT));
|
||||
if constexpr (encoding == AcceptedEncoding::ASCII) {
|
||||
static_assert(
|
||||
std::is_same_v<DestCharT, char>,
|
||||
"AcceptedEncoding::ASCII can be used only with single byte");
|
||||
}
|
||||
|
||||
const JSExternalStringCallbacks* callbacks;
|
||||
const DestCharT* chars;
|
||||
if (!MaybeGetExternalStringChars(
|
||||
s, &callbacks, reinterpret_cast<const SrcCharT**>(&chars))) {
|
||||
const SrcCharT* chars;
|
||||
if (!MaybeGetExternalStringChars(s, &callbacks, &chars)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto isAscii = [&]() {
|
||||
return mozilla::IsAscii(mozilla::Span(chars, len));
|
||||
};
|
||||
|
||||
if (callbacks == &sDOMStringExternalString) {
|
||||
if constexpr (encoding == AcceptedEncoding::ASCII) {
|
||||
if (!isAscii()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// The characters represent an existing string buffer that we shared with
|
||||
// JS. We can share that buffer ourselves if the string corresponds to
|
||||
// the whole buffer; otherwise we have to copy.
|
||||
if (chars[len] == '\0') {
|
||||
// NOTE: No need to worry about SrcCharT vs DestCharT, given
|
||||
// nsStringBuffer::FromData takes void*.
|
||||
AssignFromStringBuffer(
|
||||
nsStringBuffer::FromData(const_cast<DestCharT*>(chars)), len, dest);
|
||||
nsStringBuffer::FromData(const_cast<SrcCharT*>(chars)), len, dest);
|
||||
return true;
|
||||
}
|
||||
} else if (callbacks == &sLiteralExternalString) {
|
||||
if constexpr (encoding == AcceptedEncoding::ASCII) {
|
||||
if (!isAscii()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// The characters represent a literal string constant
|
||||
// compiled into libxul; we can just use it as-is.
|
||||
dest.AssignLiteral(chars, len);
|
||||
dest.AssignLiteral(reinterpret_cast<const DestCharT*>(chars), len);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -418,24 +359,14 @@ class XPCStringConvert {
|
|||
template <typename T>
|
||||
static MOZ_ALWAYS_INLINE bool MaybeAssignUCStringChars(JSString* s,
|
||||
size_t len, T& dest) {
|
||||
return MaybeAssignStringChars<char16_t, char16_t, AcceptedEncoding::All>(
|
||||
s, len, dest);
|
||||
return MaybeAssignStringChars<char16_t, char16_t>(s, len, dest);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static MOZ_ALWAYS_INLINE bool MaybeAssignLatin1StringChars(JSString* s,
|
||||
size_t len,
|
||||
T& dest) {
|
||||
return MaybeAssignStringChars<JS::Latin1Char, char, AcceptedEncoding::All>(
|
||||
s, len, dest);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static MOZ_ALWAYS_INLINE bool MaybeAssignUTF8StringChars(JSString* s,
|
||||
size_t len,
|
||||
T& dest) {
|
||||
return MaybeAssignStringChars<JS::Latin1Char, char,
|
||||
AcceptedEncoding::ASCII>(s, len, dest);
|
||||
return MaybeAssignStringChars<JS::Latin1Char, char>(s, len, dest);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -568,32 +499,6 @@ inline bool Latin1StringToJsval(JSContext* cx, const nsACString& str,
|
|||
return NonVoidLatin1StringToJsval(cx, str, rval);
|
||||
}
|
||||
|
||||
/**
|
||||
* As above, but for nsACString with UTF-8 content.
|
||||
*/
|
||||
bool NonVoidUTF8StringToJsval(JSContext* cx, nsACString& str,
|
||||
JS::MutableHandle<JS::Value> rval);
|
||||
bool NonVoidUTF8StringToJsval(JSContext* cx, const nsACString& str,
|
||||
JS::MutableHandle<JS::Value> rval);
|
||||
|
||||
inline bool UTF8StringToJsval(JSContext* cx, nsACString& str,
|
||||
JS::MutableHandle<JS::Value> rval) {
|
||||
if (str.IsVoid()) {
|
||||
rval.setNull();
|
||||
return true;
|
||||
}
|
||||
return NonVoidUTF8StringToJsval(cx, str, rval);
|
||||
}
|
||||
|
||||
inline bool UTF8StringToJsval(JSContext* cx, const nsACString& str,
|
||||
JS::MutableHandle<JS::Value> rval) {
|
||||
if (str.IsVoid()) {
|
||||
rval.setNull();
|
||||
return true;
|
||||
}
|
||||
return NonVoidUTF8StringToJsval(cx, str, rval);
|
||||
}
|
||||
|
||||
mozilla::BasePrincipal* GetRealmPrincipal(JS::Realm* realm);
|
||||
|
||||
void NukeAllWrappersForRealm(JSContext* cx, JS::Realm* realm,
|
||||
|
|
Загрузка…
Ссылка в новой задаче