Bug 800915 - Remove the cx parameter and simplify various APIs. r=sfink,bz

If callers want to throw, it's now their responsibility.
This commit is contained in:
Bobby Holley 2012-11-14 09:56:26 -08:00
Родитель 2988e5c227
Коммит 7c36e30523
35 изменённых файлов: 308 добавлений и 394 удалений

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

@ -6187,8 +6187,8 @@ nsContentUtils::CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
} }
if (dataLen > 0) { if (dataLen > 0) {
NS_ASSERTION(JS_IsArrayBufferObject(*aResult, aCx), "What happened?"); NS_ASSERTION(JS_IsArrayBufferObject(*aResult), "What happened?");
memcpy(JS_GetArrayBufferData(*aResult, aCx), aData.BeginReading(), dataLen); memcpy(JS_GetArrayBufferData(*aResult), aData.BeginReading(), dataLen);
} }
return NS_OK; return NS_OK;

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

@ -234,12 +234,12 @@ nsDOMMultipartFile::InitInternal(JSContext* aCx,
} }
continue; continue;
} }
if (JS_IsArrayBufferViewObject(&obj, aCx)) { if (JS_IsArrayBufferViewObject(&obj)) {
blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj, aCx), blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj),
JS_GetArrayBufferViewByteLength(&obj, aCx)); JS_GetArrayBufferViewByteLength(&obj));
continue; continue;
} }
if (JS_IsArrayBufferObject(&obj, aCx)) { if (JS_IsArrayBufferObject(&obj)) {
blobSet.AppendArrayBuffer(&obj, aCx); blobSet.AppendArrayBuffer(&obj, aCx);
continue; continue;
} }
@ -321,6 +321,6 @@ BlobSet::AppendBlobs(const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlob)
nsresult nsresult
BlobSet::AppendArrayBuffer(JSObject* aBuffer, JSContext *aCx) BlobSet::AppendArrayBuffer(JSObject* aBuffer, JSContext *aCx)
{ {
return AppendVoidPtr(JS_GetArrayBufferData(aBuffer, aCx), return AppendVoidPtr(JS_GetArrayBufferData(aBuffer),
JS_GetArrayBufferByteLength(aBuffer, aCx)); JS_GetArrayBufferByteLength(aBuffer));
} }

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

@ -317,9 +317,9 @@ nsDOMDataChannel::GetSendParams(nsIVariant* aData, nsCString& aStringOut,
nsresult rv = aData->GetAsJSVal(&realVal); nsresult rv = aData->GetAsJSVal(&realVal);
if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal) && if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal) &&
(obj = JSVAL_TO_OBJECT(realVal)) && (obj = JSVAL_TO_OBJECT(realVal)) &&
(JS_IsArrayBufferObject(obj, aCx))) { (JS_IsArrayBufferObject(obj))) {
int32_t len = JS_GetArrayBufferByteLength(obj, aCx); int32_t len = JS_GetArrayBufferByteLength(obj);
char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj, aCx)); char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj));
aStringOut.Assign(data, len); aStringOut.Assign(data, len);
aIsBinary = true; aIsBinary = true;

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

@ -309,7 +309,7 @@ nsDOMFileReader::DoOnDataAvailable(nsIRequest *aRequest,
} }
else if (mDataFormat == FILE_AS_ARRAYBUFFER) { else if (mDataFormat == FILE_AS_ARRAYBUFFER) {
uint32_t bytesRead = 0; uint32_t bytesRead = 0;
aInputStream->Read((char*)JS_GetArrayBufferData(mResultArrayBuffer, NULL) + aOffset, aInputStream->Read((char*)JS_GetArrayBufferData(mResultArrayBuffer) + aOffset,
aCount, &bytesRead); aCount, &bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data"); NS_ASSERTION(bytesRead == aCount, "failed to read data");
} }

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

@ -2669,8 +2669,8 @@ GetRequestBody(nsIVariant* aBody, nsIInputStream** aResult, uint64_t* aContentLe
if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal)) { if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal)) {
JSObject *obj = JSVAL_TO_OBJECT(realVal); JSObject *obj = JSVAL_TO_OBJECT(realVal);
ac.construct(cx, obj); ac.construct(cx, obj);
if (JS_IsArrayBufferObject(obj, cx)) { if (JS_IsArrayBufferObject(obj)) {
ArrayBuffer buf(cx, obj); ArrayBuffer buf(obj);
return GetRequestBody(&buf, aResult, aContentLength, aContentType, aCharset); return GetRequestBody(&buf, aResult, aContentLength, aContentType, aCharset);
} }
} }

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

@ -3493,7 +3493,7 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
return NS_OK; return NS_OK;
} }
uint8_t* data = JS_GetUint8ClampedArrayData(darray, aCx); uint8_t* data = JS_GetUint8ClampedArrayData(darray);
IntRect srcRect(0, 0, mWidth, mHeight); IntRect srcRect(0, 0, mWidth, mHeight);
IntRect destRect(aX, aY, aWidth, aHeight); IntRect destRect(aX, aY, aWidth, aHeight);
@ -3605,7 +3605,7 @@ CanvasRenderingContext2D::PutImageData(JSContext* cx,
return; return;
} }
dom::Uint8ClampedArray arr(cx, imageData.GetDataObject()); dom::Uint8ClampedArray arr(imageData.GetDataObject());
error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy), error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
imageData.Width(), imageData.Height(), imageData.Width(), imageData.Height(),
@ -3625,7 +3625,7 @@ CanvasRenderingContext2D::PutImageData(JSContext* cx,
return; return;
} }
dom::Uint8ClampedArray arr(cx, imageData.GetDataObject()); dom::Uint8ClampedArray arr(imageData.GetDataObject());
error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy), error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
imageData.Width(), imageData.Height(), imageData.Width(), imageData.Height(),

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

@ -3157,8 +3157,8 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width,
WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0; WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
void* data = pixels->Data(); void* data = pixels->Data();
uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj(), NULL); uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj());
int dataType = JS_GetTypedArrayType(pixels->Obj(), NULL); int dataType = JS_GetTypedArrayType(pixels->Obj());
uint32_t channels = 0; uint32_t channels = 0;
@ -4873,7 +4873,7 @@ WebGLContext::TexImage2D(JSContext* cx, WebGLenum target, WebGLint level,
return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type, return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
pixels ? pixels->Data() : 0, pixels ? pixels->Data() : 0,
pixels ? pixels->Length() : 0, pixels ? pixels->Length() : 0,
pixels ? (int)JS_GetTypedArrayType(pixels->Obj(), cx) : -1, pixels ? (int)JS_GetTypedArrayType(pixels->Obj()) : -1,
WebGLTexelConversions::Auto, false); WebGLTexelConversions::Auto, false);
} }
@ -4890,7 +4890,7 @@ WebGLContext::TexImage2D(JSContext* cx, WebGLenum target, WebGLint level,
return ErrorInvalidValue("texImage2D: null ImageData"); return ErrorInvalidValue("texImage2D: null ImageData");
} }
Uint8ClampedArray arr(cx, pixels->GetDataObject()); Uint8ClampedArray arr(pixels->GetDataObject());
return TexImage2D_base(target, level, internalformat, pixels->Width(), return TexImage2D_base(target, level, internalformat, pixels->Width(),
pixels->Height(), 4*pixels->Width(), 0, pixels->Height(), 4*pixels->Width(), 0,
format, type, arr.Data(), arr.Length(), -1, format, type, arr.Data(), arr.Length(), -1,
@ -5027,7 +5027,7 @@ WebGLContext::TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level,
return TexSubImage2D_base(target, level, xoffset, yoffset, return TexSubImage2D_base(target, level, xoffset, yoffset,
width, height, 0, format, type, width, height, 0, format, type,
pixels->Data(), pixels->Length(), pixels->Data(), pixels->Length(),
JS_GetTypedArrayType(pixels->Obj(), cx), JS_GetTypedArrayType(pixels->Obj()),
WebGLTexelConversions::Auto, false); WebGLTexelConversions::Auto, false);
} }
@ -5043,7 +5043,7 @@ WebGLContext::TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level,
if (!pixels) if (!pixels)
return ErrorInvalidValue("texSubImage2D: pixels must not be null!"); return ErrorInvalidValue("texSubImage2D: pixels must not be null!");
Uint8ClampedArray arr(cx, pixels->GetDataObject()); Uint8ClampedArray arr(pixels->GetDataObject());
return TexSubImage2D_base(target, level, xoffset, yoffset, return TexSubImage2D_base(target, level, xoffset, yoffset,
pixels->Width(), pixels->Height(), pixels->Width(), pixels->Height(),
4*pixels->Width(), format, type, 4*pixels->Width(), format, type,

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

@ -86,7 +86,7 @@ nsDOMNotifyAudioAvailableEvent::GetFrameBuffer(JSContext* aCx, jsval* aResult)
NS_DROP_JS_OBJECTS(this, nsDOMNotifyAudioAvailableEvent); NS_DROP_JS_OBJECTS(this, nsDOMNotifyAudioAvailableEvent);
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
memcpy(JS_GetFloat32ArrayData(mCachedArray, aCx), mFrameBuffer.get(), mFrameBufferLength * sizeof(float)); memcpy(JS_GetFloat32ArrayData(mCachedArray), mFrameBuffer.get(), mFrameBufferLength * sizeof(float));
*aResult = OBJECT_TO_JSVAL(mCachedArray); *aResult = OBJECT_TO_JSVAL(mCachedArray);
return NS_OK; return NS_OK;

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

@ -156,7 +156,7 @@ nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, uint32
JSObject* tsrc = NULL; JSObject* tsrc = NULL;
// Allow either Float32Array or plain JS Array // Allow either Float32Array or plain JS Array
if (JS_IsFloat32Array(darray, aCx)) { if (JS_IsFloat32Array(darray)) {
tsrc = darray; tsrc = darray;
} else if (JS_IsArrayObject(aCx, darray)) { } else if (JS_IsArrayObject(aCx, darray)) {
JSObject* nobj = JS_NewFloat32ArrayFromArray(aCx, darray); JSObject* nobj = JS_NewFloat32ArrayFromArray(aCx, darray);
@ -169,7 +169,7 @@ nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, uint32
} }
tvr.setObject(tsrc); tvr.setObject(tsrc);
uint32_t dataLength = JS_GetTypedArrayLength(tsrc, aCx); uint32_t dataLength = JS_GetTypedArrayLength(tsrc);
// Make sure that we are going to write the correct amount of data based // Make sure that we are going to write the correct amount of data based
// on number of channels. // on number of channels.
@ -180,7 +180,7 @@ nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, uint32
// Don't write more than can be written without blocking. // Don't write more than can be written without blocking.
uint32_t writeLen = NS_MIN(mAudioStream->Available(), dataLength / mChannels); uint32_t writeLen = NS_MIN(mAudioStream->Available(), dataLength / mChannels);
float* frames = JS_GetFloat32ArrayData(tsrc, aCx); float* frames = JS_GetFloat32ArrayData(tsrc);
// Convert the samples back to integers as we are using fixed point audio in // Convert the samples back to integers as we are using fixed point audio in
// the nsAudioStream. // the nsAudioStream.
// This could be optimized to avoid allocation and memcpy when // This could be optimized to avoid allocation and memcpy when

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

@ -522,9 +522,11 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
// Get the object. It might be a security wrapper, in which case we do a checked // Get the object. It might be a security wrapper, in which case we do a checked
// unwrap. // unwrap.
JSObject* origObj = JSVAL_TO_OBJECT(thisv); JSObject* origObj = JSVAL_TO_OBJECT(thisv);
JSObject* obj = js::UnwrapObjectChecked(cx, origObj); JSObject* obj = js::UnwrapObjectChecked(origObj);
if (!obj) if (!obj) {
JS_ReportError(cx, "Permission denied to access object");
return false; return false;
}
nsISupports* native; nsISupports* native;
if (!UnwrapDOMObjectToISupports(obj, native)) { if (!UnwrapDOMObjectToISupports(obj, native)) {

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

@ -245,7 +245,7 @@ IsArrayLike(JSContext* cx, JSObject* obj)
// XXXbz need to detect platform objects (including listbinding // XXXbz need to detect platform objects (including listbinding
// ones) with indexGetters here! // ones) with indexGetters here!
return JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj, cx); return JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj);
} }
inline bool inline bool
@ -272,7 +272,7 @@ IsPlatformObject(JSContext* cx, JSObject* obj)
clasp = js::GetObjectJSClass(obj); clasp = js::GetObjectJSClass(obj);
} }
return IS_WRAPPER_CLASS(js::Valueify(clasp)) || IsDOMClass(clasp) || return IS_WRAPPER_CLASS(js::Valueify(clasp)) || IsDOMClass(clasp) ||
JS_IsArrayBufferObject(obj, cx); JS_IsArrayBufferObject(obj);
} }
// U must be something that a T* can be assigned to (e.g. T* or an nsRefPtr<T>). // U must be something that a T* can be assigned to (e.g. T* or an nsRefPtr<T>).
@ -1314,6 +1314,11 @@ public:
mImpl.construct(); mImpl.construct();
} }
template <class T1>
void Construct(const T1 &t1) {
mImpl.construct(t1);
}
template <class T1, class T2> template <class T1, class T2>
void Construct(const T1 &t1, const T2 &t2) { void Construct(const T1 &t1, const T2 &t2) {
mImpl.construct(t1, t2); mImpl.construct(t1, t2);

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

@ -2589,7 +2589,7 @@ for (uint32_t i = 0; i < length; ++i) {
else: else:
declType = "NonNull<" + name + ">" declType = "NonNull<" + name + ">"
template = ( template = (
"%s.%s(cx, &${val}.toObject());\n" "%s.%s(&${val}.toObject());\n"
"if (!%s.%s().inited()) {\n" "if (!%s.%s().inited()) {\n"
"%s" # No newline here because onFailureBadType() handles that "%s" # No newline here because onFailureBadType() handles that
"}\n" % "}\n" %

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

@ -19,11 +19,11 @@ namespace dom {
* or array buffer object. * or array buffer object.
*/ */
template<typename T, template<typename T,
JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**)> JSObject* UnboxArray(JSObject*, uint32_t*, T**)>
struct TypedArray_base { struct TypedArray_base {
TypedArray_base(JSContext* cx, JSObject* obj) TypedArray_base(JSObject* obj)
{ {
mObj = UnboxArray(cx, obj, &mLength, &mData); mObj = UnboxArray(obj, &mLength, &mData);
} }
private: private:
@ -54,12 +54,12 @@ public:
template<typename T, template<typename T,
T* GetData(JSObject*, JSContext*), T* GetData(JSObject*),
JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**), JSObject* UnboxArray(JSObject*, uint32_t*, T**),
JSObject* CreateNew(JSContext*, uint32_t)> JSObject* CreateNew(JSContext*, uint32_t)>
struct TypedArray : public TypedArray_base<T,UnboxArray> { struct TypedArray : public TypedArray_base<T,UnboxArray> {
TypedArray(JSContext* cx, JSObject* obj) : TypedArray(JSObject* obj) :
TypedArray_base<T,UnboxArray>(cx, obj) TypedArray_base<T,UnboxArray>(obj)
{} {}
static inline JSObject* static inline JSObject*
@ -75,7 +75,7 @@ struct TypedArray : public TypedArray_base<T,UnboxArray> {
return NULL; return NULL;
} }
if (data) { if (data) {
T* buf = static_cast<T*>(GetData(obj, cx)); T* buf = static_cast<T*>(GetData(obj));
memcpy(buf, data, length*sizeof(T)); memcpy(buf, data, length*sizeof(T));
} }
return obj; return obj;

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

@ -218,9 +218,9 @@ GetInputStreamForJSVal(const jsval& aValue, JSContext* aCx,
if (!JSVAL_IS_PRIMITIVE(aValue)) { if (!JSVAL_IS_PRIMITIVE(aValue)) {
JSObject* obj = JSVAL_TO_OBJECT(aValue); JSObject* obj = JSVAL_TO_OBJECT(aValue);
if (JS_IsArrayBufferObject(obj, aCx)) { if (JS_IsArrayBufferObject(obj)) {
char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj, aCx)); char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj));
uint32_t length = JS_GetArrayBufferByteLength(obj, aCx); uint32_t length = JS_GetArrayBufferByteLength(obj);
rv = NS_NewByteInputStream(aInputStream, data, length, rv = NS_NewByteInputStream(aInputStream, data, length,
NS_ASSIGNMENT_COPY); NS_ASSIGNMENT_COPY);

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

@ -28,7 +28,7 @@ DeserializeUint8Array(JSRawObject aObj,
JSObject* obj = JS_NewArrayBuffer(cx, aBuffer.Length()); JSObject* obj = JS_NewArrayBuffer(cx, aBuffer.Length());
if (!obj) if (!obj)
return false; return false;
uint8_t* data = JS_GetArrayBufferData(obj, cx); uint8_t* data = JS_GetArrayBufferData(obj);
if (!data) if (!data)
return false; return false;
memcpy(data, aBuffer.Elements(), aBuffer.Length()); memcpy(data, aBuffer.Elements(), aBuffer.Length());
@ -187,10 +187,10 @@ TCPSocketChild::Send(const JS::Value& aData, JSContext* aCx)
} else { } else {
NS_ENSURE_TRUE(aData.isObject(), NS_ERROR_FAILURE); NS_ENSURE_TRUE(aData.isObject(), NS_ERROR_FAILURE);
JSObject* obj = &aData.toObject(); JSObject* obj = &aData.toObject();
NS_ENSURE_TRUE(JS_IsTypedArrayObject(obj, aCx), NS_ERROR_FAILURE); NS_ENSURE_TRUE(JS_IsTypedArrayObject(obj), NS_ERROR_FAILURE);
NS_ENSURE_TRUE(JS_IsUint8Array(obj, aCx), NS_ERROR_FAILURE); NS_ENSURE_TRUE(JS_IsUint8Array(obj), NS_ERROR_FAILURE);
uint32_t nbytes = JS_GetTypedArrayByteLength(obj, aCx); uint32_t nbytes = JS_GetTypedArrayByteLength(obj);
uint8_t* data = JS_GetUint8ArrayData(obj, aCx); uint8_t* data = JS_GetUint8ArrayData(obj);
if (!data) { if (!data) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }

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

@ -156,10 +156,10 @@ TCPSocketParent::SendCallback(const nsAString& aType, const JS::Value& aDataVal,
} else if (aDataVal.isObject()) { } else if (aDataVal.isObject()) {
JSObject* obj = &aDataVal.toObject(); JSObject* obj = &aDataVal.toObject();
if (JS_IsTypedArrayObject(obj, aCx)) { if (JS_IsTypedArrayObject(obj)) {
NS_ENSURE_TRUE(JS_IsUint8Array(obj, aCx), NS_ERROR_FAILURE); NS_ENSURE_TRUE(JS_IsUint8Array(obj), NS_ERROR_FAILURE);
uint32_t nbytes = JS_GetTypedArrayByteLength(obj, aCx); uint32_t nbytes = JS_GetTypedArrayByteLength(obj);
uint8_t* buffer = JS_GetUint8ArrayData(obj, aCx); uint8_t* buffer = JS_GetUint8ArrayData(obj);
if (!buffer) { if (!buffer) {
FireInteralError(this, __LINE__); FireInteralError(this, __LINE__);
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;

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

@ -460,20 +460,12 @@ JSValToNPVariant(NPP npp, JSContext *cx, jsval val, NPVariant *variant)
// element has since been adopted into a new document. We don't bother // element has since been adopted into a new document. We don't bother
// transplanting the plugin objects, and just do a unwrap with security // transplanting the plugin objects, and just do a unwrap with security
// checks if we encounter one of them as an argument. If the unwrap fails, // checks if we encounter one of them as an argument. If the unwrap fails,
// we clear the pending exception and just run with the original wrapped object, // we run with the original wrapped object, since sometimes there are
// since sometimes there are legitimate cases where a security wrapper ends // legitimate cases where a security wrapper ends up here (for example,
// up here (for example, Location objects, which are _always_ behind security // Location objects, which are _always_ behind security wrappers).
// wrappers).
//
// NB: In addition to clearing the pending exception, we also have to temporarily
// disable the error reporter, because SpiderMonkey calls it directly if there's
// no JS code on the stack, which might be the case here.
JSObject *obj = JSVAL_TO_OBJECT(val); JSObject *obj = JSVAL_TO_OBJECT(val);
JSErrorReporter reporter = JS_SetErrorReporter(cx, NULL); obj = js::UnwrapObjectChecked(obj);
obj = js::UnwrapObjectChecked(cx, obj);
JS_SetErrorReporter(cx, reporter);
if (!obj) { if (!obj) {
JS_ClearPendingException(cx);
obj = JSVAL_TO_OBJECT(val); obj = JSVAL_TO_OBJECT(val);
} }
@ -1134,7 +1126,7 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj)
static JSObject * static JSObject *
GetNPObjectWrapper(JSContext *cx, JSObject *obj, bool wrapResult = true) GetNPObjectWrapper(JSContext *cx, JSObject *obj, bool wrapResult = true)
{ {
while (obj && (obj = js::UnwrapObjectChecked(cx, obj))) { while (obj && (obj = js::UnwrapObjectChecked(obj))) {
if (JS_GetClass(obj) == &sNPObjectJSWrapperClass) { if (JS_GetClass(obj) == &sNPObjectJSWrapperClass) {
if (wrapResult && !JS_WrapObject(cx, &obj)) { if (wrapResult && !JS_WrapObject(cx, &obj)) {
return NULL; return NULL;

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

@ -89,12 +89,12 @@ PostToRIL(JSContext *cx, unsigned argc, jsval *vp)
data = abs.ptr(); data = abs.ptr();
} else if (!JSVAL_IS_PRIMITIVE(v)) { } else if (!JSVAL_IS_PRIMITIVE(v)) {
JSObject *obj = JSVAL_TO_OBJECT(v); JSObject *obj = JSVAL_TO_OBJECT(v);
if (!JS_IsTypedArrayObject(obj, cx)) { if (!JS_IsTypedArrayObject(obj)) {
JS_ReportError(cx, "Object passed in wasn't a typed array"); JS_ReportError(cx, "Object passed in wasn't a typed array");
return false; return false;
} }
uint32_t type = JS_GetTypedArrayType(obj, cx); uint32_t type = JS_GetTypedArrayType(obj);
if (type != js::ArrayBufferView::TYPE_INT8 && if (type != js::ArrayBufferView::TYPE_INT8 &&
type != js::ArrayBufferView::TYPE_UINT8 && type != js::ArrayBufferView::TYPE_UINT8 &&
type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) { type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) {
@ -102,8 +102,8 @@ PostToRIL(JSContext *cx, unsigned argc, jsval *vp)
return false; return false;
} }
size = JS_GetTypedArrayByteLength(obj, cx); size = JS_GetTypedArrayByteLength(obj);
data = JS_GetArrayBufferViewData(obj, cx); data = JS_GetArrayBufferViewData(obj);
} else { } else {
JS_ReportError(cx, JS_ReportError(cx,
"Incorrect argument. Expecting a string or a typed array"); "Incorrect argument. Expecting a string or a typed array");
@ -175,7 +175,7 @@ RILReceiver::DispatchRILEvent::RunTask(JSContext *aCx)
return false; return false;
} }
memcpy(JS_GetArrayBufferViewData(array, aCx), mMessage->mData, mMessage->mSize); memcpy(JS_GetArrayBufferViewData(array), mMessage->mData, mMessage->mSize);
jsval argv[] = { OBJECT_TO_JSVAL(array) }; jsval argv[] = { OBJECT_TO_JSVAL(array) };
return JS_CallFunctionName(aCx, obj, "onRILMessage", NS_ARRAY_LENGTH(argv), return JS_CallFunctionName(aCx, obj, "onRILMessage", NS_ARRAY_LENGTH(argv),
argv, argv); argv, argv);
@ -217,12 +217,12 @@ DoNetdCommand(JSContext *cx, unsigned argc, jsval *vp)
} }
} else if (!JSVAL_IS_PRIMITIVE(v)) { } else if (!JSVAL_IS_PRIMITIVE(v)) {
JSObject *obj = JSVAL_TO_OBJECT(v); JSObject *obj = JSVAL_TO_OBJECT(v);
if (!JS_IsTypedArrayObject(obj, cx)) { if (!JS_IsTypedArrayObject(obj)) {
JS_ReportError(cx, "Object passed in wasn't a typed array"); JS_ReportError(cx, "Object passed in wasn't a typed array");
return false; return false;
} }
uint32_t type = JS_GetTypedArrayType(obj, cx); uint32_t type = JS_GetTypedArrayType(obj);
if (type != js::ArrayBufferView::TYPE_INT8 && if (type != js::ArrayBufferView::TYPE_INT8 &&
type != js::ArrayBufferView::TYPE_UINT8 && type != js::ArrayBufferView::TYPE_UINT8 &&
type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) { type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) {
@ -230,13 +230,13 @@ DoNetdCommand(JSContext *cx, unsigned argc, jsval *vp)
return false; return false;
} }
size = JS_GetTypedArrayByteLength(obj, cx); size = JS_GetTypedArrayByteLength(obj);
if (!size) { if (!size) {
JS_ReportError(cx, "Typed array byte length is zero"); JS_ReportError(cx, "Typed array byte length is zero");
return false; return false;
} }
data = JS_GetArrayBufferViewData(obj, cx); data = JS_GetArrayBufferViewData(obj);
if (!data) { if (!data) {
JS_ReportError(cx, "Array buffer view data is NULL"); JS_ReportError(cx, "Array buffer view data is NULL");
return false; return false;
@ -322,7 +322,7 @@ NetdReceiver::DispatchNetdEvent::RunTask(JSContext *aCx)
return false; return false;
} }
memcpy(JS_GetUint8ArrayData(array, aCx), mMessage->mData, mMessage->mSize); memcpy(JS_GetUint8ArrayData(array), mMessage->mData, mMessage->mSize);
jsval argv[] = { OBJECT_TO_JSVAL(array) }; jsval argv[] = { OBJECT_TO_JSVAL(array) };
return JS_CallFunctionName(aCx, obj, "onNetdMessage", NS_ARRAY_LENGTH(argv), return JS_CallFunctionName(aCx, obj, "onNetdMessage", NS_ARRAY_LENGTH(argv),
argv, argv); argv, argv);

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

@ -95,8 +95,8 @@ FileReaderSync::ReadAsArrayBuffer(JSContext* aCx, JSObject* aBlob,
return nullptr; return nullptr;
} }
uint32_t bufferLength = JS_GetArrayBufferByteLength(jsArrayBuffer, aCx); uint32_t bufferLength = JS_GetArrayBufferByteLength(jsArrayBuffer);
uint8_t* arrayBuffer = JS_GetArrayBufferData(jsArrayBuffer, aCx); uint8_t* arrayBuffer = JS_GetArrayBufferData(jsArrayBuffer);
nsCOMPtr<nsIInputStream> stream; nsCOMPtr<nsIInputStream> stream;
rv = blob->GetInternalStream(getter_AddRefs(stream)); rv = blob->GetInternalStream(getter_AddRefs(stream));

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

@ -40,8 +40,8 @@ public:
Create(JSContext* aCx, uint32_t aWidth, uint32_t aHeight, JSObject *aData) Create(JSContext* aCx, uint32_t aWidth, uint32_t aHeight, JSObject *aData)
{ {
MOZ_ASSERT(aData); MOZ_ASSERT(aData);
MOZ_ASSERT(JS_IsTypedArrayObject(aData, aCx)); MOZ_ASSERT(JS_IsTypedArrayObject(aData));
MOZ_ASSERT(JS_IsUint8ClampedArray(aData, aCx)); MOZ_ASSERT(JS_IsUint8ClampedArray(aData));
JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL); JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
if (!obj) { if (!obj) {

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

@ -2008,7 +2008,7 @@ XMLHttpRequest::Send(JSObject* aBody, ErrorResult& aRv)
JSContext* cx = GetJSContext(); JSContext* cx = GetJSContext();
jsval valToClone; jsval valToClone;
if (JS_IsArrayBufferObject(aBody, cx) || file::GetDOMBlobFromJSObject(aBody)) { if (JS_IsArrayBufferObject(aBody) || file::GetDOMBlobFromJSObject(aBody)) {
valToClone = OBJECT_TO_JSVAL(aBody); valToClone = OBJECT_TO_JSVAL(aBody);
} }
else { else {

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

@ -2116,7 +2116,7 @@ bool CanConvertTypedArrayItemTo(JSObject *baseType, JSObject *valObj, JSContext
return true; return true;
} }
TypeCode elementTypeCode; TypeCode elementTypeCode;
switch (JS_GetTypedArrayType(valObj, cx)) { switch (JS_GetTypedArrayType(valObj)) {
case TypedArray::TYPE_INT8: case TypedArray::TYPE_INT8:
elementTypeCode = TYPE_int8_t; elementTypeCode = TYPE_int8_t;
break; break;
@ -2341,13 +2341,13 @@ ImplicitConvert(JSContext* cx,
return TypeError(cx, "string pointer", val); return TypeError(cx, "string pointer", val);
} }
break; break;
} else if (!JSVAL_IS_PRIMITIVE(val) && JS_IsArrayBufferObject(valObj, cx)) { } else if (!JSVAL_IS_PRIMITIVE(val) && JS_IsArrayBufferObject(valObj)) {
// Convert ArrayBuffer to pointer without any copy. // Convert ArrayBuffer to pointer without any copy.
// Just as with C arrays, we make no effort to // Just as with C arrays, we make no effort to
// keep the ArrayBuffer alive. // keep the ArrayBuffer alive.
*static_cast<void**>(buffer) = JS_GetArrayBufferData(valObj, cx); *static_cast<void**>(buffer) = JS_GetArrayBufferData(valObj);
break; break;
} if (!JSVAL_IS_PRIMITIVE(val) && JS_IsTypedArrayObject(valObj, cx)) { } if (!JSVAL_IS_PRIMITIVE(val) && JS_IsTypedArrayObject(valObj)) {
if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) { if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) {
return TypeError(cx, "typed array with the appropriate type", val); return TypeError(cx, "typed array with the appropriate type", val);
} }
@ -2355,7 +2355,7 @@ ImplicitConvert(JSContext* cx,
// Convert TypedArray to pointer without any copy. // Convert TypedArray to pointer without any copy.
// Just as with C arrays, we make no effort to // Just as with C arrays, we make no effort to
// keep the TypedArray alive. // keep the TypedArray alive.
*static_cast<void**>(buffer) = JS_GetArrayBufferViewData(valObj, cx); *static_cast<void**>(buffer) = JS_GetArrayBufferViewData(valObj);
break; break;
} }
return TypeError(cx, "pointer", val); return TypeError(cx, "pointer", val);
@ -2444,34 +2444,34 @@ ImplicitConvert(JSContext* cx,
memcpy(buffer, intermediate.get(), arraySize); memcpy(buffer, intermediate.get(), arraySize);
} else if (!JSVAL_IS_PRIMITIVE(val) && } else if (!JSVAL_IS_PRIMITIVE(val) &&
JS_IsArrayBufferObject(valObj, cx)) { JS_IsArrayBufferObject(valObj)) {
// Check that array is consistent with type, then // Check that array is consistent with type, then
// copy the array. // copy the array.
uint32_t sourceLength = JS_GetArrayBufferByteLength(valObj, cx); uint32_t sourceLength = JS_GetArrayBufferByteLength(valObj);
size_t elementSize = CType::GetSize(baseType); size_t elementSize = CType::GetSize(baseType);
size_t arraySize = elementSize * targetLength; size_t arraySize = elementSize * targetLength;
if (arraySize != size_t(sourceLength)) { if (arraySize != size_t(sourceLength)) {
JS_ReportError(cx, "ArrayType length does not match source ArrayBuffer length"); JS_ReportError(cx, "ArrayType length does not match source ArrayBuffer length");
return false; return false;
} }
memcpy(buffer, JS_GetArrayBufferData(valObj, cx), sourceLength); memcpy(buffer, JS_GetArrayBufferData(valObj), sourceLength);
break; break;
} else if (!JSVAL_IS_PRIMITIVE(val) && } else if (!JSVAL_IS_PRIMITIVE(val) &&
JS_IsTypedArrayObject(valObj, cx)) { JS_IsTypedArrayObject(valObj)) {
// Check that array is consistent with type, then // Check that array is consistent with type, then
// copy the array. // copy the array.
if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) { if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) {
return TypeError(cx, "typed array with the appropriate type", val); return TypeError(cx, "typed array with the appropriate type", val);
} }
uint32_t sourceLength = JS_GetTypedArrayByteLength(valObj, cx); uint32_t sourceLength = JS_GetTypedArrayByteLength(valObj);
size_t elementSize = CType::GetSize(baseType); size_t elementSize = CType::GetSize(baseType);
size_t arraySize = elementSize * targetLength; size_t arraySize = elementSize * targetLength;
if (arraySize != size_t(sourceLength)) { if (arraySize != size_t(sourceLength)) {
JS_ReportError(cx, "typed array length does not match source TypedArray length"); JS_ReportError(cx, "typed array length does not match source TypedArray length");
return false; return false;
} }
memcpy(buffer, JS_GetArrayBufferViewData(valObj, cx), sourceLength); memcpy(buffer, JS_GetArrayBufferViewData(valObj), sourceLength);
break; break;
} else { } else {
// Don't implicitly convert to string. Users can implicitly convert // Don't implicitly convert to string. Users can implicitly convert

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

@ -36,15 +36,15 @@ BEGIN_TEST(testArrayBuffer_bug720949_steal)
jsval v; jsval v;
// Byte lengths should all agree // Byte lengths should all agree
CHECK(JS_IsArrayBufferObject(obj, cx)); CHECK(JS_IsArrayBufferObject(obj));
CHECK_EQUAL(JS_GetArrayBufferByteLength(obj, cx), size); CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), size);
JS_GetProperty(cx, obj, "byteLength", &v); JS_GetProperty(cx, obj, "byteLength", &v);
CHECK_SAME(v, INT_TO_JSVAL(size)); CHECK_SAME(v, INT_TO_JSVAL(size));
JS_GetProperty(cx, view, "byteLength", &v); JS_GetProperty(cx, view, "byteLength", &v);
CHECK_SAME(v, INT_TO_JSVAL(size)); CHECK_SAME(v, INT_TO_JSVAL(size));
// Modifying the underlying data should update the value returned through the view // Modifying the underlying data should update the value returned through the view
uint8_t *data = JS_GetArrayBufferData(obj, cx); uint8_t *data = JS_GetArrayBufferData(obj);
CHECK(data != NULL); CHECK(data != NULL);
*reinterpret_cast<uint32_t*>(data) = MAGIC_VALUE_2; *reinterpret_cast<uint32_t*>(data) = MAGIC_VALUE_2;
CHECK(JS_GetElement(cx, view, 0, &v)); CHECK(JS_GetElement(cx, view, 0, &v));
@ -57,7 +57,7 @@ BEGIN_TEST(testArrayBuffer_bug720949_steal)
CHECK(data != NULL); CHECK(data != NULL);
// Check that the original ArrayBuffer is neutered // Check that the original ArrayBuffer is neutered
CHECK_EQUAL(JS_GetArrayBufferByteLength(obj, cx), 0); CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), 0);
CHECK(JS_GetProperty(cx, obj, "byteLength", &v)); CHECK(JS_GetProperty(cx, obj, "byteLength", &v));
CHECK_SAME(v, INT_TO_JSVAL(0)); CHECK_SAME(v, INT_TO_JSVAL(0));
CHECK(JS_GetProperty(cx, view, "byteLength", &v)); CHECK(JS_GetProperty(cx, view, "byteLength", &v));
@ -66,21 +66,21 @@ BEGIN_TEST(testArrayBuffer_bug720949_steal)
CHECK_SAME(v, INT_TO_JSVAL(0)); CHECK_SAME(v, INT_TO_JSVAL(0));
CHECK(JS_GetProperty(cx, view, "length", &v)); CHECK(JS_GetProperty(cx, view, "length", &v));
CHECK_SAME(v, INT_TO_JSVAL(0)); CHECK_SAME(v, INT_TO_JSVAL(0));
CHECK_EQUAL(JS_GetArrayBufferByteLength(obj, cx), 0); CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), 0);
v = JSVAL_VOID; v = JSVAL_VOID;
JS_GetElement(cx, obj, 0, &v); JS_GetElement(cx, obj, 0, &v);
CHECK_SAME(v, JSVAL_VOID); CHECK_SAME(v, JSVAL_VOID);
// Transfer to a new ArrayBuffer // Transfer to a new ArrayBuffer
js::RootedObject dst(cx, JS_NewArrayBufferWithContents(cx, contents)); js::RootedObject dst(cx, JS_NewArrayBufferWithContents(cx, contents));
CHECK(JS_IsArrayBufferObject(dst, cx)); CHECK(JS_IsArrayBufferObject(dst));
data = JS_GetArrayBufferData(obj, cx); data = JS_GetArrayBufferData(obj);
js::RootedObject dstview(cx, JS_NewInt32ArrayWithBuffer(cx, dst, 0, -1)); js::RootedObject dstview(cx, JS_NewInt32ArrayWithBuffer(cx, dst, 0, -1));
CHECK(dstview != NULL); CHECK(dstview != NULL);
CHECK_EQUAL(JS_GetArrayBufferByteLength(dst, cx), size); CHECK_EQUAL(JS_GetArrayBufferByteLength(dst), size);
data = JS_GetArrayBufferData(dst, cx); data = JS_GetArrayBufferData(dst);
CHECK(data != NULL); CHECK(data != NULL);
CHECK_EQUAL(*reinterpret_cast<uint32_t*>(data), MAGIC_VALUE_2); CHECK_EQUAL(*reinterpret_cast<uint32_t*>(data), MAGIC_VALUE_2);
CHECK(JS_GetElement(cx, dstview, 0, &v)); CHECK(JS_GetElement(cx, dstview, 0, &v));

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

@ -28,16 +28,16 @@ BEGIN_TEST(testTypedArrays)
size_t nbytes = sizeof(double) * 8; size_t nbytes = sizeof(double) * 8;
RootedObject buffer(cx, JS_NewArrayBuffer(cx, nbytes)); RootedObject buffer(cx, JS_NewArrayBuffer(cx, nbytes));
CHECK(JS_IsArrayBufferObject(buffer, cx)); CHECK(JS_IsArrayBufferObject(buffer));
RootedObject proto(cx); RootedObject proto(cx);
JS_GetPrototype(cx, buffer, proto.address()); JS_GetPrototype(cx, buffer, proto.address());
CHECK(!JS_IsArrayBufferObject(proto, cx)); CHECK(!JS_IsArrayBufferObject(proto));
RootedObject dummy(cx, JS_GetParent(proto)); RootedObject dummy(cx, JS_GetParent(proto));
CHECK(!JS_IsArrayBufferObject(dummy, cx)); CHECK(!JS_IsArrayBufferObject(dummy));
CHECK_EQUAL(JS_GetArrayBufferByteLength(buffer, cx), nbytes); CHECK_EQUAL(JS_GetArrayBufferByteLength(buffer), nbytes);
memset(JS_GetArrayBufferData(buffer, cx), 1, nbytes); memset(JS_GetArrayBufferData(buffer), 1, nbytes);
ok = ok && ok = ok &&
TestArrayFromBuffer<JS_NewInt8ArrayWithBuffer, JS_NewInt8ArrayFromArray, int8_t, JS_GetInt8ArrayData>(cx) && TestArrayFromBuffer<JS_NewInt8ArrayWithBuffer, JS_NewInt8ArrayFromArray, int8_t, JS_GetInt8ArrayData>(cx) &&
@ -55,24 +55,24 @@ BEGIN_TEST(testTypedArrays)
template<JSObject *Create(JSContext *, uint32_t), template<JSObject *Create(JSContext *, uint32_t),
typename Element, typename Element,
Element *GetData(JSObject *, JSContext *)> Element *GetData(JSObject *)>
bool bool
TestPlainTypedArray(JSContext *cx) TestPlainTypedArray(JSContext *cx)
{ {
RootedObject array(cx, Create(cx, 7)); RootedObject array(cx, Create(cx, 7));
CHECK(JS_IsTypedArrayObject(array, cx)); CHECK(JS_IsTypedArrayObject(array));
RootedObject proto(cx); RootedObject proto(cx);
JS_GetPrototype(cx, array, proto.address()); JS_GetPrototype(cx, array, proto.address());
CHECK(!JS_IsTypedArrayObject(proto, cx)); CHECK(!JS_IsTypedArrayObject(proto));
RootedObject dummy(cx, JS_GetParent(proto)); RootedObject dummy(cx, JS_GetParent(proto));
CHECK(!JS_IsTypedArrayObject(dummy, cx)); CHECK(!JS_IsTypedArrayObject(dummy));
CHECK_EQUAL(JS_GetTypedArrayLength(array, cx), 7); CHECK_EQUAL(JS_GetTypedArrayLength(array), 7);
CHECK_EQUAL(JS_GetTypedArrayByteOffset(array, cx), 0); CHECK_EQUAL(JS_GetTypedArrayByteOffset(array), 0);
CHECK_EQUAL(JS_GetTypedArrayByteLength(array, cx), sizeof(Element) * 7); CHECK_EQUAL(JS_GetTypedArrayByteLength(array), sizeof(Element) * 7);
Element *data; Element *data;
CHECK(data = GetData(array, cx)); CHECK(data = GetData(array));
*data = 13; *data = 13;
jsval v; jsval v;
CHECK(JS_GetElement(cx, array, 0, &v)); CHECK(JS_GetElement(cx, array, 0, &v));
@ -84,7 +84,7 @@ TestPlainTypedArray(JSContext *cx)
template<JSObject *CreateWithBuffer(JSContext *, JSObject *, uint32_t, int32_t), template<JSObject *CreateWithBuffer(JSContext *, JSObject *, uint32_t, int32_t),
JSObject *CreateFromArray(JSContext *, JSObject *), JSObject *CreateFromArray(JSContext *, JSObject *),
typename Element, typename Element,
Element *GetData(JSObject *, JSContext *)> Element *GetData(JSObject *)>
bool bool
TestArrayFromBuffer(JSContext *cx) TestArrayFromBuffer(JSContext *cx)
{ {
@ -92,32 +92,32 @@ TestArrayFromBuffer(JSContext *cx)
size_t nbytes = elts * sizeof(Element); size_t nbytes = elts * sizeof(Element);
RootedObject buffer(cx, JS_NewArrayBuffer(cx, nbytes)); RootedObject buffer(cx, JS_NewArrayBuffer(cx, nbytes));
uint8_t *bufdata; uint8_t *bufdata;
CHECK(bufdata = JS_GetArrayBufferData(buffer, cx)); CHECK(bufdata = JS_GetArrayBufferData(buffer));
memset(bufdata, 1, nbytes); memset(bufdata, 1, nbytes);
RootedObject array(cx, CreateWithBuffer(cx, buffer, 0, -1)); RootedObject array(cx, CreateWithBuffer(cx, buffer, 0, -1));
CHECK_EQUAL(JS_GetTypedArrayLength(array, cx), elts); CHECK_EQUAL(JS_GetTypedArrayLength(array), elts);
CHECK_EQUAL(JS_GetTypedArrayByteOffset(array, cx), 0); CHECK_EQUAL(JS_GetTypedArrayByteOffset(array), 0);
CHECK_EQUAL(JS_GetTypedArrayByteLength(array, cx), nbytes); CHECK_EQUAL(JS_GetTypedArrayByteLength(array), nbytes);
CHECK_EQUAL(JS_GetArrayBufferViewBuffer(array, cx), (JSObject*) buffer); CHECK_EQUAL(JS_GetArrayBufferViewBuffer(array), (JSObject*) buffer);
Element *data; Element *data;
CHECK(data = GetData(array, cx)); CHECK(data = GetData(array));
CHECK(bufdata = JS_GetArrayBufferData(buffer, cx)); CHECK(bufdata = JS_GetArrayBufferData(buffer));
CHECK_EQUAL((void*) data, (void*) bufdata); CHECK_EQUAL((void*) data, (void*) bufdata);
CHECK_EQUAL(*bufdata, 1); CHECK_EQUAL(*bufdata, 1);
CHECK_EQUAL(*reinterpret_cast<uint8_t*>(data), 1); CHECK_EQUAL(*reinterpret_cast<uint8_t*>(data), 1);
RootedObject shortArray(cx, CreateWithBuffer(cx, buffer, 0, elts / 2)); RootedObject shortArray(cx, CreateWithBuffer(cx, buffer, 0, elts / 2));
CHECK_EQUAL(JS_GetTypedArrayLength(shortArray, cx), elts / 2); CHECK_EQUAL(JS_GetTypedArrayLength(shortArray), elts / 2);
CHECK_EQUAL(JS_GetTypedArrayByteOffset(shortArray, cx), 0); CHECK_EQUAL(JS_GetTypedArrayByteOffset(shortArray), 0);
CHECK_EQUAL(JS_GetTypedArrayByteLength(shortArray, cx), nbytes / 2); CHECK_EQUAL(JS_GetTypedArrayByteLength(shortArray), nbytes / 2);
RootedObject ofsArray(cx, CreateWithBuffer(cx, buffer, nbytes / 2, -1)); RootedObject ofsArray(cx, CreateWithBuffer(cx, buffer, nbytes / 2, -1));
CHECK_EQUAL(JS_GetTypedArrayLength(ofsArray, cx), elts / 2); CHECK_EQUAL(JS_GetTypedArrayLength(ofsArray), elts / 2);
CHECK_EQUAL(JS_GetTypedArrayByteOffset(ofsArray, cx), nbytes / 2); CHECK_EQUAL(JS_GetTypedArrayByteOffset(ofsArray), nbytes / 2);
CHECK_EQUAL(JS_GetTypedArrayByteLength(ofsArray, cx), nbytes / 2); CHECK_EQUAL(JS_GetTypedArrayByteLength(ofsArray), nbytes / 2);
// Make sure all 3 views reflect the same buffer at the expected locations // Make sure all 3 views reflect the same buffer at the expected locations
jsval v = INT_TO_JSVAL(39); jsval v = INT_TO_JSVAL(39);

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

@ -567,13 +567,13 @@ JS_WriteTypedArray(JSStructuredCloneWriter *w, jsval v)
JS_ASSERT(v.isObject()); JS_ASSERT(v.isObject());
RootedObject obj(w->context(), &v.toObject()); RootedObject obj(w->context(), &v.toObject());
// If the object is a security wrapper, try puncturing it. This may throw // If the object is a security wrapper, see if we're allowed to unwrap it.
// if the access is not allowed. // If we aren't, throw.
if (obj->isWrapper()) { if (obj->isWrapper())
JSObject *unwrapped = UnwrapObjectChecked(w->context(), obj); obj = UnwrapObjectChecked(obj);
if (!unwrapped) if (!obj) {
return false; JS_ReportError(w->context(), "Permission denied to access object");
obj = unwrapped; return false;
} }
return w->writeTypedArray(obj); return w->writeTypedArray(obj);
} }
@ -674,9 +674,11 @@ JSStructuredCloneWriter::startWrite(const Value &v)
// The object might be a security wrapper. See if we can clone what's // The object might be a security wrapper. See if we can clone what's
// behind it. If we can, unwrap the object. // behind it. If we can, unwrap the object.
obj = UnwrapObjectChecked(context(), obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj) {
JS_ReportError(context(), "Permission denied to access object");
return false; return false;
}
AutoCompartment ac(context(), obj); AutoCompartment ac(context(), obj);
@ -897,23 +899,23 @@ JSStructuredCloneReader::readTypedArray(uint32_t tag, uint32_t nelems, Value *vp
JS_ASSERT(TypedArray::length(obj) == nelems); JS_ASSERT(TypedArray::length(obj) == nelems);
switch (tag) { switch (tag) {
case SCTAG_TYPED_ARRAY_INT8: case SCTAG_TYPED_ARRAY_INT8:
return in.readArray((uint8_t*) JS_GetInt8ArrayData(obj, context()), nelems); return in.readArray((uint8_t*) JS_GetInt8ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_UINT8: case SCTAG_TYPED_ARRAY_UINT8:
return in.readArray(JS_GetUint8ArrayData(obj, context()), nelems); return in.readArray(JS_GetUint8ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_INT16: case SCTAG_TYPED_ARRAY_INT16:
return in.readArray((uint16_t*) JS_GetInt16ArrayData(obj, context()), nelems); return in.readArray((uint16_t*) JS_GetInt16ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_UINT16: case SCTAG_TYPED_ARRAY_UINT16:
return in.readArray(JS_GetUint16ArrayData(obj, context()), nelems); return in.readArray(JS_GetUint16ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_INT32: case SCTAG_TYPED_ARRAY_INT32:
return in.readArray((uint32_t*) JS_GetInt32ArrayData(obj, context()), nelems); return in.readArray((uint32_t*) JS_GetInt32ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_UINT32: case SCTAG_TYPED_ARRAY_UINT32:
return in.readArray(JS_GetUint32ArrayData(obj, context()), nelems); return in.readArray(JS_GetUint32ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_FLOAT32: case SCTAG_TYPED_ARRAY_FLOAT32:
return in.readArray((uint32_t*) JS_GetFloat32ArrayData(obj, context()), nelems); return in.readArray((uint32_t*) JS_GetFloat32ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_FLOAT64: case SCTAG_TYPED_ARRAY_FLOAT64:
return in.readArray((uint64_t*) JS_GetFloat64ArrayData(obj, context()), nelems); return in.readArray((uint64_t*) JS_GetFloat64ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_UINT8_CLAMPED: case SCTAG_TYPED_ARRAY_UINT8_CLAMPED:
return in.readArray(JS_GetUint8ClampedArrayData(obj, context()), nelems); return in.readArray(JS_GetUint8ClampedArrayData(obj), nelems);
default: default:
JS_NOT_REACHED("unknown TypedArray type"); JS_NOT_REACHED("unknown TypedArray type");
return false; return false;

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

@ -1183,41 +1183,40 @@ JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes);
* the various accessor JSAPI calls defined below. * the various accessor JSAPI calls defined below.
*/ */
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsTypedArrayObject(JSObject *obj, JSContext *cx); JS_IsTypedArrayObject(JSObject *obj);
/* /*
* Check whether obj supports JS_GetArrayBufferView* APIs. Note that this may * Check whether obj supports JS_GetArrayBufferView* APIs. Note that this may
* return false if a security wrapper is encountered that denies the * return false if a security wrapper is encountered that denies the
* unwrapping. If this test or one of the more specific tests succeeds, then it * unwrapping. If this test or one of the more specific tests succeeds, then it
* is safe to call the various ArrayBufferView accessor JSAPI calls defined * is safe to call the various ArrayBufferView accessor JSAPI calls defined
* below. cx MUST be non-NULL and valid. * below.
*/ */
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsArrayBufferViewObject(JSObject *obj, JSContext *cx); JS_IsArrayBufferViewObject(JSObject *obj);
/* /*
* Test for specific typed array types (ArrayBufferView subtypes) * Test for specific typed array types (ArrayBufferView subtypes)
*/ */
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsInt8Array(JSObject *obj, JSContext *cx); JS_IsInt8Array(JSObject *obj);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsUint8Array(JSObject *obj, JSContext *cx); JS_IsUint8Array(JSObject *obj);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsUint8ClampedArray(JSObject *obj, JSContext *cx); JS_IsUint8ClampedArray(JSObject *obj);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsInt16Array(JSObject *obj, JSContext *cx); JS_IsInt16Array(JSObject *obj);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsUint16Array(JSObject *obj, JSContext *cx); JS_IsUint16Array(JSObject *obj);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsInt32Array(JSObject *obj, JSContext *cx); JS_IsInt32Array(JSObject *obj);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsUint32Array(JSObject *obj, JSContext *cx); JS_IsUint32Array(JSObject *obj);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsFloat32Array(JSObject *obj, JSContext *cx); JS_IsFloat32Array(JSObject *obj);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsFloat64Array(JSObject *obj, JSContext *cx); JS_IsFloat64Array(JSObject *obj);
/* /*
* Unwrap Typed arrays all at once. Return NULL without throwing if the object * Unwrap Typed arrays all at once. Return NULL without throwing if the object
@ -1225,38 +1224,37 @@ JS_IsFloat64Array(JSObject *obj, JSContext *cx);
* success, filling both outparameters. * success, filling both outparameters.
*/ */
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetObjectAsInt8Array(JSContext *cx, JSObject *obj, uint32_t *length, int8_t **data); JS_GetObjectAsInt8Array(JSObject *obj, uint32_t *length, int8_t **data);
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetObjectAsUint8Array(JSContext *cx, JSObject *obj, uint32_t *length, uint8_t **data); JS_GetObjectAsUint8Array(JSObject *obj, uint32_t *length, uint8_t **data);
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetObjectAsUint8ClampedArray(JSContext *cx, JSObject *obj, uint32_t *length, uint8_t **data); JS_GetObjectAsUint8ClampedArray(JSObject *obj, uint32_t *length, uint8_t **data);
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetObjectAsInt16Array(JSContext *cx, JSObject *obj, uint32_t *length, int16_t **data); JS_GetObjectAsInt16Array(JSObject *obj, uint32_t *length, int16_t **data);
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetObjectAsUint16Array(JSContext *cx, JSObject *obj, uint32_t *length, uint16_t **data); JS_GetObjectAsUint16Array(JSObject *obj, uint32_t *length, uint16_t **data);
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetObjectAsInt32Array(JSContext *cx, JSObject *obj, uint32_t *length, int32_t **data); JS_GetObjectAsInt32Array(JSObject *obj, uint32_t *length, int32_t **data);
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetObjectAsUint32Array(JSContext *cx, JSObject *obj, uint32_t *length, uint32_t **data); JS_GetObjectAsUint32Array(JSObject *obj, uint32_t *length, uint32_t **data);
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetObjectAsFloat32Array(JSContext *cx, JSObject *obj, uint32_t *length, float **data); JS_GetObjectAsFloat32Array(JSObject *obj, uint32_t *length, float **data);
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetObjectAsFloat64Array(JSContext *cx, JSObject *obj, uint32_t *length, double **data); JS_GetObjectAsFloat64Array(JSObject *obj, uint32_t *length, double **data);
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetObjectAsArrayBufferView(JSContext *cx, JSObject *obj, uint32_t *length, uint8_t **data); JS_GetObjectAsArrayBufferView(JSObject *obj, uint32_t *length, uint8_t **data);
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetObjectAsArrayBuffer(JSContext *cx, JSObject *obj, uint32_t *length, uint8_t **data); JS_GetObjectAsArrayBuffer(JSObject *obj, uint32_t *length, uint8_t **data);
/* /*
* Get the type of elements in a typed array. * Get the type of elements in a typed array.
* *
* |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
* be known that it would pass such a test: it is a typed array or a wrapper of * be known that it would pass such a test: it is a typed array or a wrapper of
* a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG * a typed array, and the unwrapping will succeed.
* builds may be unable to assert when unwrapping should be disallowed.
*/ */
extern JS_FRIEND_API(JSArrayBufferViewType) extern JS_FRIEND_API(JSArrayBufferViewType)
JS_GetTypedArrayType(JSObject *obj, JSContext *maybecx); JS_GetTypedArrayType(JSObject *obj);
/* /*
* Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may * Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may
@ -1265,18 +1263,17 @@ JS_GetTypedArrayType(JSObject *obj, JSContext *maybecx);
* accessor JSAPI calls defined below. * accessor JSAPI calls defined below.
*/ */
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsArrayBufferObject(JSObject *obj, JSContext *maybecx); JS_IsArrayBufferObject(JSObject *obj);
/* /*
* Return the available byte length of an array buffer. * Return the available byte length of an array buffer.
* *
* |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
* that it would pass such a test: it is an ArrayBuffer or a wrapper of an * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
* ArrayBuffer, and the unwrapping will succeed. If cx is NULL, then DEBUG * ArrayBuffer, and the unwrapping will succeed.
* builds may be unable to assert when unwrapping should be disallowed.
*/ */
extern JS_FRIEND_API(uint32_t) extern JS_FRIEND_API(uint32_t)
JS_GetArrayBufferByteLength(JSObject *obj, JSContext *maybecx); JS_GetArrayBufferByteLength(JSObject *obj);
/* /*
* Return a pointer to an array buffer's data. The buffer is still owned by the * Return a pointer to an array buffer's data. The buffer is still owned by the
@ -1285,22 +1282,20 @@ JS_GetArrayBufferByteLength(JSObject *obj, JSContext *maybecx);
* *
* |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
* that it would pass such a test: it is an ArrayBuffer or a wrapper of an * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
* ArrayBuffer, and the unwrapping will succeed. If cx is NULL, then DEBUG * ArrayBuffer, and the unwrapping will succeed.
* builds may be unable to assert when unwrapping should be disallowed.
*/ */
extern JS_FRIEND_API(uint8_t *) extern JS_FRIEND_API(uint8_t *)
JS_GetArrayBufferData(JSObject *obj, JSContext *maybecx); JS_GetArrayBufferData(JSObject *obj);
/* /*
* Return the number of elements in a typed array. * Return the number of elements in a typed array.
* *
* |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
* be known that it would pass such a test: it is a typed array or a wrapper of * be known that it would pass such a test: it is a typed array or a wrapper of
* a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG * a typed array, and the unwrapping will succeed.
* builds may be unable to assert when unwrapping should be disallowed.
*/ */
extern JS_FRIEND_API(uint32_t) extern JS_FRIEND_API(uint32_t)
JS_GetTypedArrayLength(JSObject *obj, JSContext *cx); JS_GetTypedArrayLength(JSObject *obj);
/* /*
* Return the byte offset from the start of an array buffer to the start of a * Return the byte offset from the start of an array buffer to the start of a
@ -1308,22 +1303,20 @@ JS_GetTypedArrayLength(JSObject *obj, JSContext *cx);
* *
* |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
* be known that it would pass such a test: it is a typed array or a wrapper of * be known that it would pass such a test: it is a typed array or a wrapper of
* a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG * a typed array, and the unwrapping will succeed.
* builds may be unable to assert when unwrapping should be disallowed.
*/ */
extern JS_FRIEND_API(uint32_t) extern JS_FRIEND_API(uint32_t)
JS_GetTypedArrayByteOffset(JSObject *obj, JSContext *cx); JS_GetTypedArrayByteOffset(JSObject *obj);
/* /*
* Return the byte length of a typed array. * Return the byte length of a typed array.
* *
* |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
* be known that it would pass such a test: it is a typed array or a wrapper of * be known that it would pass such a test: it is a typed array or a wrapper of
* a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG * a typed array, and the unwrapping will succeed.
* builds may be unable to assert when unwrapping should be disallowed.
*/ */
extern JS_FRIEND_API(uint32_t) extern JS_FRIEND_API(uint32_t)
JS_GetTypedArrayByteLength(JSObject *obj, JSContext *cx); JS_GetTypedArrayByteLength(JSObject *obj);
/* /*
* Check whether obj supports JS_ArrayBufferView* APIs. Note that this may * Check whether obj supports JS_ArrayBufferView* APIs. Note that this may
@ -1331,13 +1324,13 @@ JS_GetTypedArrayByteLength(JSObject *obj, JSContext *cx);
* unwrapping. * unwrapping.
*/ */
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
JS_IsArrayBufferViewObject(JSObject *obj, JSContext *cx); JS_IsArrayBufferViewObject(JSObject *obj);
/* /*
* More generic name for JS_GetTypedArrayByteLength to cover DataViews as well * More generic name for JS_GetTypedArrayByteLength to cover DataViews as well
*/ */
extern JS_FRIEND_API(uint32_t) extern JS_FRIEND_API(uint32_t)
JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *cx); JS_GetArrayBufferViewByteLength(JSObject *obj);
/* /*
* Return a pointer to the start of the data referenced by a typed array. The * Return a pointer to the start of the data referenced by a typed array. The
@ -1346,35 +1339,34 @@ JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *cx);
* *
* |obj| must have passed a JS_Is*Array test, or somehow be known that it would * |obj| must have passed a JS_Is*Array test, or somehow be known that it would
* pass such a test: it is a typed array or a wrapper of a typed array, and the * pass such a test: it is a typed array or a wrapper of a typed array, and the
* unwrapping will succeed. If cx is NULL, then DEBUG builds may be unable to * unwrapping will succeed.
* assert when unwrapping should be disallowed.
*/ */
extern JS_FRIEND_API(int8_t *) extern JS_FRIEND_API(int8_t *)
JS_GetInt8ArrayData(JSObject *obj, JSContext *maybecx); JS_GetInt8ArrayData(JSObject *obj);
extern JS_FRIEND_API(uint8_t *) extern JS_FRIEND_API(uint8_t *)
JS_GetUint8ArrayData(JSObject *obj, JSContext *maybecx); JS_GetUint8ArrayData(JSObject *obj);
extern JS_FRIEND_API(uint8_t *) extern JS_FRIEND_API(uint8_t *)
JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *maybecx); JS_GetUint8ClampedArrayData(JSObject *obj);
extern JS_FRIEND_API(int16_t *) extern JS_FRIEND_API(int16_t *)
JS_GetInt16ArrayData(JSObject *obj, JSContext *maybecx); JS_GetInt16ArrayData(JSObject *obj);
extern JS_FRIEND_API(uint16_t *) extern JS_FRIEND_API(uint16_t *)
JS_GetUint16ArrayData(JSObject *obj, JSContext *maybecx); JS_GetUint16ArrayData(JSObject *obj);
extern JS_FRIEND_API(int32_t *) extern JS_FRIEND_API(int32_t *)
JS_GetInt32ArrayData(JSObject *obj, JSContext *maybecx); JS_GetInt32ArrayData(JSObject *obj);
extern JS_FRIEND_API(uint32_t *) extern JS_FRIEND_API(uint32_t *)
JS_GetUint32ArrayData(JSObject *obj, JSContext *maybecx); JS_GetUint32ArrayData(JSObject *obj);
extern JS_FRIEND_API(float *) extern JS_FRIEND_API(float *)
JS_GetFloat32ArrayData(JSObject *obj, JSContext *maybecx); JS_GetFloat32ArrayData(JSObject *obj);
extern JS_FRIEND_API(double *) extern JS_FRIEND_API(double *)
JS_GetFloat64ArrayData(JSObject *obj, JSContext *maybecx); JS_GetFloat64ArrayData(JSObject *obj);
/* /*
* Same as above, but for any kind of ArrayBufferView. Prefer the type-specific * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific
* versions when possible. * versions when possible.
*/ */
extern JS_FRIEND_API(void *) extern JS_FRIEND_API(void *)
JS_GetArrayBufferViewData(JSObject *obj, JSContext *maybecx); JS_GetArrayBufferViewData(JSObject *obj);
/* /*
* Return the ArrayBuffer underlying an ArrayBufferView. If the buffer has been * Return the ArrayBuffer underlying an ArrayBufferView. If the buffer has been
@ -1382,15 +1374,13 @@ JS_GetArrayBufferViewData(JSObject *obj, JSContext *maybecx);
* object that would return true for JS_IsArrayBufferViewObject(). * object that would return true for JS_IsArrayBufferViewObject().
*/ */
extern JS_FRIEND_API(JSObject *) extern JS_FRIEND_API(JSObject *)
JS_GetArrayBufferViewBuffer(JSObject *obj, JSContext *maybecx); JS_GetArrayBufferViewBuffer(JSObject *obj);
/* /*
* Check whether obj supports JS_GetDataView* APIs. Note that this may fail and * Check whether obj supports JS_GetDataView* APIs.
* throw an exception if a security wrapper is encountered that denies the
* operation.
*/ */
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
JS_IsDataViewObject(JSContext *cx, JSObject *obj, JSBool *isDataView); JS_IsDataViewObject(JSObject *obj);
/* /*
* Return the byte offset of a data view into its array buffer. |obj| must be a * Return the byte offset of a data view into its array buffer. |obj| must be a
@ -1398,11 +1388,10 @@ JS_IsDataViewObject(JSContext *cx, JSObject *obj, JSBool *isDataView);
* *
* |obj| must have passed a JS_IsDataViewObject test, or somehow be known that * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that
* it would pass such a test: it is a data view or a wrapper of a data view, * it would pass such a test: it is a data view or a wrapper of a data view,
* and the unwrapping will succeed. If cx is NULL, then DEBUG builds may be * and the unwrapping will succeed.
* unable to assert when unwrapping should be disallowed.
*/ */
JS_FRIEND_API(uint32_t) JS_FRIEND_API(uint32_t)
JS_GetDataViewByteOffset(JSObject *obj, JSContext *maybecx); JS_GetDataViewByteOffset(JSObject *obj);
/* /*
* Return the byte length of a data view. * Return the byte length of a data view.
@ -1413,7 +1402,7 @@ JS_GetDataViewByteOffset(JSObject *obj, JSContext *maybecx);
* unable to assert when unwrapping should be disallowed. * unable to assert when unwrapping should be disallowed.
*/ */
JS_FRIEND_API(uint32_t) JS_FRIEND_API(uint32_t)
JS_GetDataViewByteLength(JSObject *obj, JSContext *maybecx); JS_GetDataViewByteLength(JSObject *obj);
/* /*
* Return a pointer to the beginning of the data referenced by a DataView. * Return a pointer to the beginning of the data referenced by a DataView.
@ -1424,7 +1413,7 @@ JS_GetDataViewByteLength(JSObject *obj, JSContext *maybecx);
* unable to assert when unwrapping should be disallowed. * unable to assert when unwrapping should be disallowed.
*/ */
JS_FRIEND_API(void *) JS_FRIEND_API(void *)
JS_GetDataViewData(JSObject *obj, JSContext *maybecx); JS_GetDataViewData(JSObject *obj);
/* /*
* This struct contains metadata passed from the DOM to the JS Engine for JIT * This struct contains metadata passed from the DOM to the JS Engine for JIT

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

@ -174,16 +174,10 @@ fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, MutableHandleValu
return false; return false;
/* /*
* Censor the caller if we can't PUNCTURE it. * Censor the caller if we don't have full access to it.
*
* NB - This will get much much nicer with bug 800915
*/ */
JSObject &caller = vp.toObject(); JSObject &caller = vp.toObject();
JSErrorReporter reporter = JS_SetErrorReporter(cx, NULL); if (caller.isWrapper() && !Wrapper::wrapperHandler(&caller)->isSafeToUnwrap()) {
bool punctureThrew = !UnwrapObjectChecked(cx, &caller);
JS_SetErrorReporter(cx, reporter);
if (punctureThrew) {
JS_ClearPendingException(cx);
vp.setNull(); vp.setNull();
} else if (caller.isFunction()) { } else if (caller.isFunction()) {
JSFunction *callerFun = caller.toFunction(); JSFunction *callerFun = caller.toFunction();

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

@ -1873,9 +1873,11 @@ class TypedArrayTemplate
* compartment for a view in the target compartment referencing the * compartment for a view in the target compartment referencing the
* ArrayBuffer in that same compartment. * ArrayBuffer in that same compartment.
*/ */
JSObject *wrapped = UnwrapObjectChecked(cx, bufobj); JSObject *wrapped = UnwrapObjectChecked(bufobj);
if (!wrapped) if (!wrapped) {
JS_ReportError(cx, "Permission denied to access object");
return NULL; return NULL;
}
if (wrapped->isArrayBuffer()) { if (wrapped->isArrayBuffer()) {
/* /*
* And for even more fun, the new view's prototype should be * And for even more fun, the new view's prototype should be
@ -3141,13 +3143,10 @@ JSFunctionSpec _typedArray::jsfuncs[] = { \
return TypedArrayTemplate<NativeType>::fromBuffer(cx, arrayBuffer, byteoffset, length, \ return TypedArrayTemplate<NativeType>::fromBuffer(cx, arrayBuffer, byteoffset, length, \
proto); \ proto); \
} \ } \
JS_FRIEND_API(JSBool) JS_Is ## Name ## Array(JSObject *obj, JSContext *cx) \ JS_FRIEND_API(JSBool) JS_Is ## Name ## Array(JSObject *obj) \
{ \ { \
MOZ_ASSERT(!cx->isExceptionPending()); \ if (!(obj = UnwrapObjectChecked(obj))) \
if (!(obj = UnwrapObjectChecked(cx, obj))) { \
cx->clearPendingException(); \
return false; \ return false; \
} \
Class *clasp = obj->getClass(); \ Class *clasp = obj->getClass(); \
return (clasp == &TypedArray::classes[TypedArrayTemplate<NativeType>::ArrayTypeID()]); \ return (clasp == &TypedArray::classes[TypedArrayTemplate<NativeType>::ArrayTypeID()]); \
} }
@ -3163,18 +3162,12 @@ IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Float32, float)
IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Float64, double) IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Float64, double)
#define IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Name, ExternalType, InternalType) \ #define IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Name, ExternalType, InternalType) \
JS_FRIEND_API(JSObject *) JS_GetObjectAs ## Name ## Array(JSContext *cx, \ JS_FRIEND_API(JSObject *) JS_GetObjectAs ## Name ## Array(JSObject *obj, \
JSObject *obj, \
uint32_t *length, \ uint32_t *length, \
ExternalType **data) \ ExternalType **data) \
{ \ { \
if (obj->isWrapper()) { \ if (!(obj = UnwrapObjectChecked(obj))) \
MOZ_ASSERT(!cx->isExceptionPending()); \ return NULL; \
if (!(obj = UnwrapObjectChecked(cx, obj))) { \
cx->clearPendingException(); \
return NULL; \
} \
} \
\ \
Class *clasp = obj->getClass(); \ Class *clasp = obj->getClass(); \
if (clasp != &TypedArray::classes[TypedArrayTemplate<InternalType>::ArrayTypeID()]) \ if (clasp != &TypedArray::classes[TypedArrayTemplate<InternalType>::ArrayTypeID()]) \
@ -3571,76 +3564,42 @@ js_InitTypedArrayClasses(JSContext *cx, HandleObject obj)
/* JS Friend API */ /* JS Friend API */
// The typed array friend API defines a number of accessor functions that want JS_FRIEND_API(JSBool)
// to unwrap an argument, but in certain rare cases may not have a cx available JS_IsArrayBufferObject(JSObject *obj)
// and so pass in NULL instead. Use UnwrapObjectChecked when possible.
static JSObject *
CheckedUnwrap(JSContext *cx, JSObject *obj)
{ {
if (!cx) obj = UnwrapObjectChecked(obj);
return UnwrapObject(obj); return obj ? obj->isArrayBuffer() : false;
MOZ_ASSERT(!cx->isExceptionPending());
obj = UnwrapObjectChecked(cx, obj);
MOZ_ASSERT(obj);
return obj;
} }
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
JS_IsArrayBufferObject(JSObject *objArg, JSContext *cx) JS_IsTypedArrayObject(JSObject *obj)
{ {
RootedObject obj_(cx, objArg); obj = UnwrapObjectChecked(obj);
MOZ_ASSERT(!cx->isExceptionPending()); return obj ? obj->isTypedArray() : false;
JSObject *obj = UnwrapObjectChecked(cx, obj_);
if (!obj) {
cx->clearPendingException();
return false;
}
return obj->isArrayBuffer();
} }
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
JS_IsTypedArrayObject(JSObject *objArg, JSContext *cx) JS_IsArrayBufferViewObject(JSObject *obj)
{ {
RootedObject obj_(cx, objArg); obj = UnwrapObjectChecked(obj);
MOZ_ASSERT(!cx->isExceptionPending()); return obj ? (obj->isTypedArray() || obj->isDataView()) : false;
JSObject *obj = UnwrapObjectChecked(cx, obj_);
if (!obj) {
cx->clearPendingException();
return false;
}
return obj->isTypedArray();
}
JS_FRIEND_API(JSBool)
JS_IsArrayBufferViewObject(JSObject *objArg, JSContext *cx)
{
RootedObject obj_(cx, objArg);
MOZ_ASSERT(!cx->isExceptionPending());
JSObject *obj = UnwrapObjectChecked(cx, obj_);
if (!obj) {
cx->clearPendingException();
return false;
}
return obj->isTypedArray() || obj->isDataView();
} }
JS_FRIEND_API(uint32_t) JS_FRIEND_API(uint32_t)
JS_GetArrayBufferByteLength(JSObject *obj, JSContext *maybecx) JS_GetArrayBufferByteLength(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) return obj ? obj->asArrayBuffer().byteLength() : 0;
return 0;
return obj->asArrayBuffer().byteLength();
} }
JS_FRIEND_API(uint8_t *) JS_FRIEND_API(uint8_t *)
JS_GetArrayBufferData(JSObject *obj, JSContext *maybecx) JS_GetArrayBufferData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
ArrayBufferObject &buffer = obj->asArrayBuffer(); ArrayBufferObject &buffer = obj->asArrayBuffer();
if (!buffer.uninlineData(maybecx)) if (!buffer.uninlineData(NULL))
return NULL; return NULL;
return buffer.dataPointer(); return buffer.dataPointer();
} }
@ -3680,7 +3639,7 @@ JS_PUBLIC_API(JSBool)
JS_StealArrayBufferContents(JSContext *cx, JSObject *obj, void **contents, JS_StealArrayBufferContents(JSContext *cx, JSObject *obj, void **contents,
uint8_t **data) uint8_t **data)
{ {
if (!(obj = UnwrapObjectChecked(cx, obj))) if (!(obj = UnwrapObjectChecked(obj)))
return false; return false;
if (!obj->isArrayBuffer()) { if (!obj->isArrayBuffer()) {
@ -3695,9 +3654,9 @@ JS_StealArrayBufferContents(JSContext *cx, JSObject *obj, void **contents,
} }
JS_FRIEND_API(uint32_t) JS_FRIEND_API(uint32_t)
JS_GetTypedArrayLength(JSObject *obj, JSContext *maybecx) JS_GetTypedArrayLength(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return 0; return 0;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3705,9 +3664,9 @@ JS_GetTypedArrayLength(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(uint32_t) JS_FRIEND_API(uint32_t)
JS_GetTypedArrayByteOffset(JSObject *obj, JSContext *maybecx) JS_GetTypedArrayByteOffset(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return 0; return 0;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3715,9 +3674,9 @@ JS_GetTypedArrayByteOffset(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(uint32_t) JS_FRIEND_API(uint32_t)
JS_GetTypedArrayByteLength(JSObject *obj, JSContext *maybecx) JS_GetTypedArrayByteLength(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return 0; return 0;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3725,9 +3684,9 @@ JS_GetTypedArrayByteLength(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(JSArrayBufferViewType) JS_FRIEND_API(JSArrayBufferViewType)
JS_GetTypedArrayType(JSObject *obj, JSContext *maybecx) JS_GetTypedArrayType(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return ArrayBufferView::TYPE_MAX; return ArrayBufferView::TYPE_MAX;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3735,9 +3694,9 @@ JS_GetTypedArrayType(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(int8_t *) JS_FRIEND_API(int8_t *)
JS_GetInt8ArrayData(JSObject *obj, JSContext *maybecx) JS_GetInt8ArrayData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3746,9 +3705,9 @@ JS_GetInt8ArrayData(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(uint8_t *) JS_FRIEND_API(uint8_t *)
JS_GetUint8ArrayData(JSObject *obj, JSContext *maybecx) JS_GetUint8ArrayData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3757,9 +3716,9 @@ JS_GetUint8ArrayData(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(uint8_t *) JS_FRIEND_API(uint8_t *)
JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *maybecx) JS_GetUint8ClampedArrayData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3768,9 +3727,9 @@ JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(int16_t *) JS_FRIEND_API(int16_t *)
JS_GetInt16ArrayData(JSObject *obj, JSContext *maybecx) JS_GetInt16ArrayData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3779,9 +3738,9 @@ JS_GetInt16ArrayData(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(uint16_t *) JS_FRIEND_API(uint16_t *)
JS_GetUint16ArrayData(JSObject *obj, JSContext *maybecx) JS_GetUint16ArrayData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3790,9 +3749,9 @@ JS_GetUint16ArrayData(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(int32_t *) JS_FRIEND_API(int32_t *)
JS_GetInt32ArrayData(JSObject *obj, JSContext *maybecx) JS_GetInt32ArrayData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3801,9 +3760,9 @@ JS_GetInt32ArrayData(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(uint32_t *) JS_FRIEND_API(uint32_t *)
JS_GetUint32ArrayData(JSObject *obj, JSContext *maybecx) JS_GetUint32ArrayData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3812,9 +3771,9 @@ JS_GetUint32ArrayData(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(float *) JS_FRIEND_API(float *)
JS_GetFloat32ArrayData(JSObject *obj, JSContext *maybecx) JS_GetFloat32ArrayData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3823,9 +3782,9 @@ JS_GetFloat32ArrayData(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(double *) JS_FRIEND_API(double *)
JS_GetFloat64ArrayData(JSObject *obj, JSContext *maybecx) JS_GetFloat64ArrayData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isTypedArray()); JS_ASSERT(obj->isTypedArray());
@ -3834,29 +3793,25 @@ JS_GetFloat64ArrayData(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
JS_IsDataViewObject(JSContext *cx, JSObject *objArg, JSBool *isDataView) JS_IsDataViewObject(JSObject *obj)
{ {
RootedObject obj_(cx, objArg); obj = UnwrapObjectChecked(obj);
JSObject *obj = CheckedUnwrap(cx, obj_); return obj ? obj->isDataView() : false;
if (!obj)
return false;
*isDataView = obj->isDataView();
return true;
} }
JS_FRIEND_API(uint32_t) JS_FRIEND_API(uint32_t)
JS_GetDataViewByteOffset(JSObject *obj, JSContext *maybecx) JS_GetDataViewByteOffset(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return 0; return 0;
return obj->asDataView().byteOffset(); return obj->asDataView().byteOffset();
} }
JS_FRIEND_API(void *) JS_FRIEND_API(void *)
JS_GetDataViewData(JSObject *obj, JSContext *maybecx) JS_GetDataViewData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isDataView()); JS_ASSERT(obj->isDataView());
@ -3864,9 +3819,9 @@ JS_GetDataViewData(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(uint32_t) JS_FRIEND_API(uint32_t)
JS_GetDataViewByteLength(JSObject *obj, JSContext *maybecx) JS_GetDataViewByteLength(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return 0; return 0;
JS_ASSERT(obj->isDataView()); JS_ASSERT(obj->isDataView());
@ -3874,9 +3829,9 @@ JS_GetDataViewByteLength(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(void *) JS_FRIEND_API(void *)
JS_GetArrayBufferViewData(JSObject *obj, JSContext *maybecx) JS_GetArrayBufferViewData(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isTypedArray() || obj->isDataView()); JS_ASSERT(obj->isTypedArray() || obj->isDataView());
@ -3884,9 +3839,9 @@ JS_GetArrayBufferViewData(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(JSObject *) JS_FRIEND_API(JSObject *)
JS_GetArrayBufferViewBuffer(JSObject *obj, JSContext *maybecx) JS_GetArrayBufferViewBuffer(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return NULL; return NULL;
JS_ASSERT(obj->isTypedArray() || obj->isDataView()); JS_ASSERT(obj->isTypedArray() || obj->isDataView());
@ -3894,9 +3849,9 @@ JS_GetArrayBufferViewBuffer(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(uint32_t) JS_FRIEND_API(uint32_t)
JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *maybecx) JS_GetArrayBufferViewByteLength(JSObject *obj)
{ {
obj = CheckedUnwrap(maybecx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj)
return 0; return 0;
JS_ASSERT(obj->isTypedArray() || obj->isDataView()); JS_ASSERT(obj->isTypedArray() || obj->isDataView());
@ -3906,15 +3861,10 @@ JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *maybecx)
} }
JS_FRIEND_API(JSObject *) JS_FRIEND_API(JSObject *)
JS_GetObjectAsArrayBufferView(JSContext *cx, JSObject *obj, JS_GetObjectAsArrayBufferView(JSObject *obj, uint32_t *length, uint8_t **data)
uint32_t *length, uint8_t **data)
{ {
if (obj->isWrapper()) { if (!(obj = UnwrapObjectChecked(obj)))
if (!(obj = UnwrapObjectChecked(cx, obj))) { return NULL;
cx->clearPendingException();
return NULL;
}
}
if (!(obj->isTypedArray() || obj->isDataView())) if (!(obj->isTypedArray() || obj->isDataView()))
return NULL; return NULL;
@ -3927,14 +3877,10 @@ JS_GetObjectAsArrayBufferView(JSContext *cx, JSObject *obj,
} }
JS_FRIEND_API(JSObject *) JS_FRIEND_API(JSObject *)
JS_GetObjectAsArrayBuffer(JSContext *cx, JSObject *obj, uint32_t *length, uint8_t **data) JS_GetObjectAsArrayBuffer(JSObject *obj, uint32_t *length, uint8_t **data)
{ {
if (obj->isWrapper()) { if (!(obj = UnwrapObjectChecked(obj)))
if (!(obj = UnwrapObjectChecked(cx, obj))) { return NULL;
cx->clearPendingException();
return NULL;
}
}
if (!obj->isArrayBuffer()) if (!obj->isArrayBuffer())
return NULL; return NULL;

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

@ -109,19 +109,18 @@ js::UnwrapObject(JSObject *wrapped, bool stopAtOuter, unsigned *flagsp)
} }
JS_FRIEND_API(JSObject *) JS_FRIEND_API(JSObject *)
js::UnwrapObjectChecked(JSContext *cx, RawObject objArg) js::UnwrapObjectChecked(RawObject obj)
{ {
RootedObject obj(cx, objArg);
while (true) { while (true) {
JSObject *wrapper = obj; JSObject *wrapper = obj;
obj = UnwrapOneChecked(cx, obj); obj = UnwrapOneChecked(obj);
if (!obj || obj == wrapper) if (!obj || obj == wrapper)
return obj; return obj;
} }
} }
JS_FRIEND_API(JSObject *) JS_FRIEND_API(JSObject *)
js::UnwrapOneChecked(JSContext *cx, HandleObject obj) js::UnwrapOneChecked(RawObject obj)
{ {
// Checked unwraps should never unwrap outer windows. // Checked unwraps should never unwrap outer windows.
if (!obj->isWrapper() || if (!obj->isWrapper() ||
@ -131,11 +130,7 @@ js::UnwrapOneChecked(JSContext *cx, HandleObject obj)
} }
Wrapper *handler = Wrapper::wrapperHandler(obj); Wrapper *handler = Wrapper::wrapperHandler(obj);
if (!handler->isSafeToUnwrap()) { return handler->isSafeToUnwrap() ? Wrapper::wrappedObject(obj) : NULL;
JS_ReportError(cx, "Permission denied to access object");
return NULL;
}
return Wrapper::wrappedObject(obj);
} }
bool bool

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

@ -255,12 +255,12 @@ UnwrapObject(JSObject *obj, bool stopAtOuter = true, unsigned *flagsp = NULL);
// code should never be unwrapping outer window wrappers, we always stop at // code should never be unwrapping outer window wrappers, we always stop at
// outer windows. // outer windows.
JS_FRIEND_API(JSObject *) JS_FRIEND_API(JSObject *)
UnwrapObjectChecked(JSContext *cx, RawObject obj); UnwrapObjectChecked(RawObject obj);
// Unwrap only the outermost security wrapper, with the same semantics as // Unwrap only the outermost security wrapper, with the same semantics as
// above. This is the checked version of Wrapper::wrappedObject. // above. This is the checked version of Wrapper::wrappedObject.
JS_FRIEND_API(JSObject *) JS_FRIEND_API(JSObject *)
UnwrapOneChecked(JSContext *cx, HandleObject obj); UnwrapOneChecked(RawObject obj);
JS_FRIEND_API(bool) JS_FRIEND_API(bool)
IsCrossCompartmentWrapper(RawObject obj); IsCrossCompartmentWrapper(RawObject obj);

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

@ -1819,9 +1819,11 @@ Debugger::unwrapDebuggeeArgument(JSContext *cx, const Value &v)
} }
/* If we have a cross-compartment wrapper, dereference as far as is secure. */ /* If we have a cross-compartment wrapper, dereference as far as is secure. */
obj = UnwrapObjectChecked(cx, obj); obj = UnwrapObjectChecked(obj);
if (!obj) if (!obj) {
JS_ReportError(cx, "Permission denied to access object");
return NULL; return NULL;
}
/* If that produced an outer window, innerize it. */ /* If that produced an outer window, innerize it. */
obj = GetInnerObject(cx, obj); obj = GetInnerObject(cx, obj);
@ -4465,18 +4467,8 @@ static JSBool
DebuggerObject_unwrap(JSContext *cx, unsigned argc, Value *vp) DebuggerObject_unwrap(JSContext *cx, unsigned argc, Value *vp)
{ {
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "unwrap", args, dbg, referent); THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "unwrap", args, dbg, referent);
JSObject *unwrapped = UnwrapOneChecked(cx, referent); JSObject *unwrapped = UnwrapOneChecked(referent);
if (!unwrapped) { if (!unwrapped) {
// If we were terminated, then pass that along.
if (!cx->isExceptionPending())
return false;
// If the unwrap operation threw an exception, assume it's a
// security exception, and return null. It seems like the wrappers
// in use in Firefox just call JS_ReportError, so we have no way to
// distinguish genuine should-not-unwrap errors from other kinds of
// errors.
cx->clearPendingException();
vp->setNull(); vp->setNull();
return true; return true;
} }

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

@ -2711,7 +2711,7 @@ nsXPCComponents_Utils::LookupMethod(const JS::Value& object,
// we don't have full access to the other compartment, in which case we throw. // we don't have full access to the other compartment, in which case we throw.
// Otherwise, enter the compartment. // Otherwise, enter the compartment.
if (js::IsCrossCompartmentWrapper(obj)) { if (js::IsCrossCompartmentWrapper(obj)) {
obj = js::UnwrapOneChecked(cx, obj); obj = js::UnwrapOneChecked(obj);
if (!obj) if (!obj)
return NS_ERROR_XPC_BAD_CONVERT_JS; return NS_ERROR_XPC_BAD_CONVERT_JS;
} }
@ -3863,7 +3863,7 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
{ {
JS_AbortIfWrongThread(JS_GetRuntime(cx)); JS_AbortIfWrongThread(JS_GetRuntime(cx));
sandbox = js::UnwrapObjectChecked(cx, sandbox); sandbox = js::UnwrapObjectChecked(sandbox);
if (!sandbox || js::GetObjectJSClass(sandbox) != &SandboxClass) { if (!sandbox || js::GetObjectJSClass(sandbox) != &SandboxClass) {
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
} }

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

@ -1483,8 +1483,7 @@ failure:
// of the output does not exceed UINT32_MAX bytes. Allocate // of the output does not exceed UINT32_MAX bytes. Allocate
// the memory and copy the elements by memcpy. // the memory and copy the elements by memcpy.
static JSBool static JSBool
CheckTargetAndPopulate(JSContext *cx, CheckTargetAndPopulate(const nsXPTType& type,
const nsXPTType& type,
uint8_t requiredType, uint8_t requiredType,
size_t typeSize, size_t typeSize,
uint32_t count, uint32_t count,
@ -1515,7 +1514,7 @@ CheckTargetAndPopulate(JSContext *cx,
return false; return false;
} }
memcpy(*output, JS_GetArrayBufferViewData(tArr, cx), byteSize); memcpy(*output, JS_GetArrayBufferViewData(tArr), byteSize);
return true; return true;
} }
@ -1529,8 +1528,7 @@ CheckTargetAndPopulate(JSContext *cx,
// static // static
JSBool JSBool
XPCConvert::JSTypedArray2Native(JSContext* cx, XPCConvert::JSTypedArray2Native(void** d,
void** d,
JSObject* jsArray, JSObject* jsArray,
uint32_t count, uint32_t count,
const nsXPTType& type, const nsXPTType& type,
@ -1538,11 +1536,11 @@ XPCConvert::JSTypedArray2Native(JSContext* cx,
{ {
NS_ABORT_IF_FALSE(jsArray, "bad param"); NS_ABORT_IF_FALSE(jsArray, "bad param");
NS_ABORT_IF_FALSE(d, "bad param"); NS_ABORT_IF_FALSE(d, "bad param");
NS_ABORT_IF_FALSE(JS_IsTypedArrayObject(jsArray, cx), "not a typed array"); NS_ABORT_IF_FALSE(JS_IsTypedArrayObject(jsArray), "not a typed array");
// Check the actual length of the input array against the // Check the actual length of the input array against the
// given size_is. // given size_is.
uint32_t len = JS_GetTypedArrayLength(jsArray, cx); uint32_t len = JS_GetTypedArrayLength(jsArray);
if (len < count) { if (len < count) {
if (pErr) if (pErr)
*pErr = NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY; *pErr = NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY;
@ -1552,9 +1550,9 @@ XPCConvert::JSTypedArray2Native(JSContext* cx,
void* output = nullptr; void* output = nullptr;
switch (JS_GetTypedArrayType(jsArray, cx)) { switch (JS_GetTypedArrayType(jsArray)) {
case js::ArrayBufferView::TYPE_INT8: case js::ArrayBufferView::TYPE_INT8:
if (!CheckTargetAndPopulate(cx, nsXPTType::T_I8, type, if (!CheckTargetAndPopulate(nsXPTType::T_I8, type,
sizeof(int8_t), count, sizeof(int8_t), count,
jsArray, &output, pErr)) { jsArray, &output, pErr)) {
return false; return false;
@ -1563,7 +1561,7 @@ XPCConvert::JSTypedArray2Native(JSContext* cx,
case js::ArrayBufferView::TYPE_UINT8: case js::ArrayBufferView::TYPE_UINT8:
case js::ArrayBufferView::TYPE_UINT8_CLAMPED: case js::ArrayBufferView::TYPE_UINT8_CLAMPED:
if (!CheckTargetAndPopulate(cx, nsXPTType::T_U8, type, if (!CheckTargetAndPopulate(nsXPTType::T_U8, type,
sizeof(uint8_t), count, sizeof(uint8_t), count,
jsArray, &output, pErr)) { jsArray, &output, pErr)) {
return false; return false;
@ -1571,7 +1569,7 @@ XPCConvert::JSTypedArray2Native(JSContext* cx,
break; break;
case js::ArrayBufferView::TYPE_INT16: case js::ArrayBufferView::TYPE_INT16:
if (!CheckTargetAndPopulate(cx, nsXPTType::T_I16, type, if (!CheckTargetAndPopulate(nsXPTType::T_I16, type,
sizeof(int16_t), count, sizeof(int16_t), count,
jsArray, &output, pErr)) { jsArray, &output, pErr)) {
return false; return false;
@ -1579,7 +1577,7 @@ XPCConvert::JSTypedArray2Native(JSContext* cx,
break; break;
case js::ArrayBufferView::TYPE_UINT16: case js::ArrayBufferView::TYPE_UINT16:
if (!CheckTargetAndPopulate(cx, nsXPTType::T_U16, type, if (!CheckTargetAndPopulate(nsXPTType::T_U16, type,
sizeof(uint16_t), count, sizeof(uint16_t), count,
jsArray, &output, pErr)) { jsArray, &output, pErr)) {
return false; return false;
@ -1587,7 +1585,7 @@ XPCConvert::JSTypedArray2Native(JSContext* cx,
break; break;
case js::ArrayBufferView::TYPE_INT32: case js::ArrayBufferView::TYPE_INT32:
if (!CheckTargetAndPopulate(cx, nsXPTType::T_I32, type, if (!CheckTargetAndPopulate(nsXPTType::T_I32, type,
sizeof(int32_t), count, sizeof(int32_t), count,
jsArray, &output, pErr)) { jsArray, &output, pErr)) {
return false; return false;
@ -1595,7 +1593,7 @@ XPCConvert::JSTypedArray2Native(JSContext* cx,
break; break;
case js::ArrayBufferView::TYPE_UINT32: case js::ArrayBufferView::TYPE_UINT32:
if (!CheckTargetAndPopulate(cx, nsXPTType::T_U32, type, if (!CheckTargetAndPopulate(nsXPTType::T_U32, type,
sizeof(uint32_t), count, sizeof(uint32_t), count,
jsArray, &output, pErr)) { jsArray, &output, pErr)) {
return false; return false;
@ -1603,7 +1601,7 @@ XPCConvert::JSTypedArray2Native(JSContext* cx,
break; break;
case js::ArrayBufferView::TYPE_FLOAT32: case js::ArrayBufferView::TYPE_FLOAT32:
if (!CheckTargetAndPopulate(cx, nsXPTType::T_FLOAT, type, if (!CheckTargetAndPopulate(nsXPTType::T_FLOAT, type,
sizeof(float), count, sizeof(float), count,
jsArray, &output, pErr)) { jsArray, &output, pErr)) {
return false; return false;
@ -1611,7 +1609,7 @@ XPCConvert::JSTypedArray2Native(JSContext* cx,
break; break;
case js::ArrayBufferView::TYPE_FLOAT64: case js::ArrayBufferView::TYPE_FLOAT64:
if (!CheckTargetAndPopulate(cx, nsXPTType::T_DOUBLE, type, if (!CheckTargetAndPopulate(nsXPTType::T_DOUBLE, type,
sizeof(double), count, sizeof(double), count,
jsArray, &output, pErr)) { jsArray, &output, pErr)) {
return false; return false;
@ -1665,8 +1663,8 @@ XPCConvert::JSArray2Native(JSContext* cx, void** d, JS::Value s,
JSObject* jsarray = &s.toObject(); JSObject* jsarray = &s.toObject();
// If this is a typed array, then try a fast conversion with memcpy. // If this is a typed array, then try a fast conversion with memcpy.
if (JS_IsTypedArrayObject(jsarray, cx)) { if (JS_IsTypedArrayObject(jsarray)) {
return JSTypedArray2Native(cx, d, jsarray, count, type, pErr); return JSTypedArray2Native(d, jsarray, count, type, pErr);
} }
if (!JS_IsArrayObject(cx, jsarray)) { if (!JS_IsArrayObject(cx, jsarray)) {

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

@ -3368,8 +3368,7 @@ public:
uint32_t count, const nsXPTType& type, uint32_t count, const nsXPTType& type,
const nsID* iid, nsresult* pErr); const nsID* iid, nsresult* pErr);
static JSBool JSTypedArray2Native(JSContext* cx, static JSBool JSTypedArray2Native(void** d,
void** d,
JSObject* jsarray, JSObject* jsarray,
uint32_t count, uint32_t count,
const nsXPTType& type, const nsXPTType& type,

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

@ -354,7 +354,7 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
// Always permit access to "length" and indexed properties of arrays. // Always permit access to "length" and indexed properties of arrays.
if ((JS_IsArrayObject(cx, wrappedObject) || if ((JS_IsArrayObject(cx, wrappedObject) ||
JS_IsTypedArrayObject(wrappedObject, cx)) && JS_IsTypedArrayObject(wrappedObject)) &&
((JSID_IS_INT(id) && JSID_TO_INT(id) >= 0) || ((JSID_IS_INT(id) && JSID_TO_INT(id) >= 0) ||
(JSID_IS_STRING(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "length")))) { (JSID_IS_STRING(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "length")))) {
return true; // Allow return true; // Allow