mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-08 08:48:39 +09:00
Fix a longstanding IndexedDB correctness issue.
Standards Compliance fix, port of Bug 1492737
This commit is contained in:
parent
107ddd1148
commit
930cc1db3b
5 changed files with 99 additions and 17 deletions
|
|
@ -14,6 +14,7 @@
|
|||
#include "xpcpublic.h"
|
||||
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/IDBObjectStoreBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
|
@ -100,7 +101,6 @@ GetJSValFromKeyPathString(JSContext* aCx,
|
|||
const char16_t* keyPathChars = token.BeginReading();
|
||||
const size_t keyPathLen = token.Length();
|
||||
|
||||
bool hasProp;
|
||||
if (!targetObject) {
|
||||
// We're still walking the chain of existing objects
|
||||
// http://w3c.github.io/IndexedDB/#dfn-evaluate-a-key-path-on-a-value
|
||||
|
|
@ -116,16 +116,77 @@ GetJSValFromKeyPathString(JSContext* aCx,
|
|||
}
|
||||
obj = ¤tVal.toObject();
|
||||
|
||||
bool ok = JS_HasUCProperty(aCx, obj, keyPathChars, keyPathLen,
|
||||
&hasProp);
|
||||
// We call JS_GetOwnUCPropertyDescriptor on purpose (as opposed to
|
||||
// JS_GetUCPropertyDescriptor) to avoid searching the prototype chain.
|
||||
JS::Rooted<JS::PropertyDescriptor> desc(aCx);
|
||||
bool ok = JS_GetOwnUCPropertyDescriptor(aCx, obj, keyPathChars,
|
||||
keyPathLen, &desc);
|
||||
IDB_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (hasProp) {
|
||||
// Get if the property exists...
|
||||
JS::Rooted<JS::Value> intermediate(aCx);
|
||||
bool ok = JS_GetUCProperty(aCx, obj, keyPathChars, keyPathLen, &intermediate);
|
||||
IDB_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
JS::Rooted<JS::Value> intermediate(aCx);
|
||||
bool hasProp = false;
|
||||
|
||||
if (desc.object()) {
|
||||
intermediate = desc.value();
|
||||
hasProp = true;
|
||||
} else {
|
||||
// If we get here it means the object doesn't have the property or the
|
||||
// property is available throuch a getter. We don't want to call any
|
||||
// getters to avoid potential re-entrancy.
|
||||
// The blob object is special since its properties are available
|
||||
// only through getters but we still want to support them for key
|
||||
// extraction. So they need to be handled manually.
|
||||
Blob* blob;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, &obj, blob))) {
|
||||
if (token.EqualsLiteral("size")) {
|
||||
ErrorResult rv;
|
||||
uint64_t size = blob->GetSize(rv);
|
||||
MOZ_ALWAYS_TRUE(!rv.Failed());
|
||||
|
||||
intermediate = JS_NumberValue(size);
|
||||
hasProp = true;
|
||||
} else if (token.EqualsLiteral("type")) {
|
||||
nsString type;
|
||||
blob->GetType(type);
|
||||
|
||||
JSString* string =
|
||||
JS_NewUCStringCopyN(aCx, type.get(), type.Length());
|
||||
|
||||
intermediate = JS::StringValue(string);
|
||||
hasProp = true;
|
||||
} else {
|
||||
RefPtr<File> file = blob->ToFile();
|
||||
if (file) {
|
||||
if (token.EqualsLiteral("name")) {
|
||||
nsString name;
|
||||
file->GetName(name);
|
||||
|
||||
JSString* string =
|
||||
JS_NewUCStringCopyN(aCx, name.get(), name.Length());
|
||||
|
||||
intermediate = JS::StringValue(string);
|
||||
hasProp = true;
|
||||
} else if (token.EqualsLiteral("lastModified")) {
|
||||
ErrorResult rv;
|
||||
int64_t lastModifiedDate = file->GetLastModified(rv);
|
||||
MOZ_ALWAYS_TRUE(!rv.Failed());
|
||||
|
||||
intermediate = JS_NumberValue(lastModifiedDate);
|
||||
hasProp = true;
|
||||
} else if (token.EqualsLiteral("lastModifiedDate")) {
|
||||
ErrorResult rv;
|
||||
Date lastModifiedDate = file->GetLastModifiedDate(rv);
|
||||
MOZ_ALWAYS_TRUE(!rv.Failed());
|
||||
|
||||
lastModifiedDate.ToDateObject(aCx, &intermediate);
|
||||
hasProp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasProp) {
|
||||
// Treat explicitly undefined as an error.
|
||||
if (intermediate.isUndefined()) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
|
|
|
|||
|
|
@ -1049,7 +1049,8 @@ nsXBLBinding::DoInitJSClass(JSContext *cx,
|
|||
// to create and define it.
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
JS::Rooted<JS::PropertyDescriptor> desc(cx);
|
||||
if (!JS_GetOwnUCPropertyDescriptor(cx, holder, aClassName.get(), &desc)) {
|
||||
if (!JS_GetOwnUCPropertyDescriptor(cx, holder, aClassName.get(),
|
||||
aClassName.Length(), &desc)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aNew = !desc.object();
|
||||
|
|
|
|||
|
|
@ -100,11 +100,15 @@ nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
|
|||
// end up with a different content prototype, but we'll already have a property
|
||||
// holder called |foo| in the XBL scope. Check for that to avoid wasteful and
|
||||
// weird property holder duplication.
|
||||
const char16_t* className = aPrototypeBinding->ClassName().get();
|
||||
const nsString& className = aPrototypeBinding->ClassName();
|
||||
const char16_t* classNameChars = className.get();
|
||||
const size_t classNameLen = className.Length();
|
||||
|
||||
JS::Rooted<JSObject*> propertyHolder(cx);
|
||||
JS::Rooted<JS::PropertyDescriptor> existingHolder(cx);
|
||||
if (scopeObject != globalObject &&
|
||||
!JS_GetOwnUCPropertyDescriptor(cx, scopeObject, className, &existingHolder)) {
|
||||
!JS_GetOwnUCPropertyDescriptor(cx, scopeObject, classNameChars,
|
||||
classNameLen, &existingHolder)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
bool propertyHolderIsNew = !existingHolder.object() || !existingHolder.value().isObject();
|
||||
|
|
@ -119,8 +123,8 @@ nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
|
|||
|
||||
// Define it as a property on the scopeObject, using the same name used on
|
||||
// the content side.
|
||||
bool ok = JS_DefineUCProperty(cx, scopeObject, className, -1, propertyHolder,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
bool ok = JS_DefineUCProperty(cx, scopeObject, classNameChars, classNameLen,
|
||||
propertyHolder, JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
JS_STUBGETTER, JS_STUBSETTER);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2003,10 +2003,10 @@ JS_GetOwnPropertyDescriptor(JSContext* cx, HandleObject obj, const char* name,
|
|||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetOwnUCPropertyDescriptor(JSContext* cx, HandleObject obj, const char16_t* name,
|
||||
JS_GetOwnUCPropertyDescriptor(JSContext* cx, HandleObject obj, const char16_t* name, size_t namelen,
|
||||
MutableHandle<PropertyDescriptor> desc)
|
||||
{
|
||||
JSAtom* atom = AtomizeChars(cx, name, js_strlen(name));
|
||||
JSAtom* atom = AtomizeChars(cx, name, namelen);
|
||||
if (!atom)
|
||||
return false;
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
|
|
@ -2028,7 +2028,19 @@ JS_GetPropertyDescriptor(JSContext* cx, HandleObject obj, const char* name,
|
|||
if (!atom)
|
||||
return false;
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
return atom && JS_GetPropertyDescriptorById(cx, obj, id, desc);
|
||||
return JS_GetPropertyDescriptorById(cx, obj, id, desc);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetUCPropertyDescriptor(JSContext* cx, HandleObject obj, const char16_t* name, size_t namelen,
|
||||
MutableHandle<PropertyDescriptor> desc)
|
||||
{
|
||||
JSAtom* atom = AtomizeChars(cx, name, namelen);
|
||||
if (!atom) {
|
||||
return false;
|
||||
}
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
return JS_GetPropertyDescriptorById(cx, obj, id, desc);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
|||
|
|
@ -2917,7 +2917,7 @@ JS_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* nam
|
|||
JS::MutableHandle<JS::PropertyDescriptor> desc);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name,
|
||||
JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
|
||||
JS::MutableHandle<JS::PropertyDescriptor> desc);
|
||||
|
||||
/**
|
||||
|
|
@ -2934,6 +2934,10 @@ extern JS_PUBLIC_API(bool)
|
|||
JS_GetPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name,
|
||||
JS::MutableHandle<JS::PropertyDescriptor> desc);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
|
||||
JS::MutableHandle<JS::PropertyDescriptor> desc);
|
||||
|
||||
/**
|
||||
* Define a property on obj.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue