author | Bobby Holley <bobbyholley@gmail.com> |
Mon, 12 Nov 2012 17:35:32 -0800 | |
changeset 113047 | de9fff3a523240b175c0aca822911011b926d64d |
parent 113046 | c567df2244f59d53a71467afa461a12adad8ba7f |
child 113048 | 0d124d4f28b0d3365ae7c4ec0ab4b2a99e399405 |
push id | 17907 |
push user | bobbyholley@gmail.com |
push date | Tue, 13 Nov 2012 01:36:00 +0000 |
treeherder | mozilla-inbound@de9fff3a5232 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | sfink, bz |
bugs | 800915 |
milestone | 19.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -6182,18 +6182,18 @@ nsContentUtils::CreateArrayBuffer(JSCont int32_t dataLen = aData.Length(); *aResult = JS_NewArrayBuffer(aCx, dataLen); if (!*aResult) { return NS_ERROR_FAILURE; } if (dataLen > 0) { - NS_ASSERTION(JS_IsArrayBufferObject(*aResult, aCx), "What happened?"); - memcpy(JS_GetArrayBufferData(*aResult, aCx), aData.BeginReading(), dataLen); + NS_ASSERTION(JS_IsArrayBufferObject(*aResult), "What happened?"); + memcpy(JS_GetArrayBufferData(*aResult), aData.BeginReading(), dataLen); } return NS_OK; } // Initial implementation: only stores to RAM, not file // TODO: bug 704447: large file support nsresult
--- a/content/base/src/nsDOMBlobBuilder.cpp +++ b/content/base/src/nsDOMBlobBuilder.cpp @@ -229,22 +229,22 @@ nsDOMMultipartFile::InitInternal(JSConte subBlobs = file->GetSubBlobs(); if (subBlobs) { blobSet.AppendBlobs(*subBlobs); } else { blobSet.AppendBlob(blob); } continue; } - if (JS_IsArrayBufferViewObject(&obj, aCx)) { - blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj, aCx), - JS_GetArrayBufferViewByteLength(&obj, aCx)); + if (JS_IsArrayBufferViewObject(&obj)) { + blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj), + JS_GetArrayBufferViewByteLength(&obj)); continue; } - if (JS_IsArrayBufferObject(&obj, aCx)) { + if (JS_IsArrayBufferObject(&obj)) { blobSet.AppendArrayBuffer(&obj, aCx); continue; } // neither Blob nor ArrayBuffer(View) } else if (element.isString()) { blobSet.AppendString(element.toString(), nativeEOL, aCx); continue; } @@ -316,11 +316,11 @@ BlobSet::AppendBlobs(const nsTArray<nsCO mBlobs.AppendElements(aBlob); return NS_OK; } nsresult BlobSet::AppendArrayBuffer(JSObject* aBuffer, JSContext *aCx) { - return AppendVoidPtr(JS_GetArrayBufferData(aBuffer, aCx), - JS_GetArrayBufferByteLength(aBuffer, aCx)); + return AppendVoidPtr(JS_GetArrayBufferData(aBuffer), + JS_GetArrayBufferByteLength(aBuffer)); }
--- a/content/base/src/nsDOMDataChannel.cpp +++ b/content/base/src/nsDOMDataChannel.cpp @@ -312,19 +312,19 @@ nsDOMDataChannel::GetSendParams(nsIVaria nsMemory::Free(iid); // ArrayBuffer? jsval realVal; JSObject* obj; nsresult rv = aData->GetAsJSVal(&realVal); if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal) && (obj = JSVAL_TO_OBJECT(realVal)) && - (JS_IsArrayBufferObject(obj, aCx))) { - int32_t len = JS_GetArrayBufferByteLength(obj, aCx); - char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj, aCx)); + (JS_IsArrayBufferObject(obj))) { + int32_t len = JS_GetArrayBufferByteLength(obj); + char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj)); aStringOut.Assign(data, len); aIsBinary = true; aOutgoingLength = len; return NS_OK; } // Blob?
--- a/content/base/src/nsDOMFileReader.cpp +++ b/content/base/src/nsDOMFileReader.cpp @@ -304,17 +304,17 @@ nsDOMFileReader::DoOnDataAvailable(nsIRe uint32_t bytesRead = 0; aInputStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount, &bytesRead); NS_ASSERTION(bytesRead == aCount, "failed to read data"); } else if (mDataFormat == FILE_AS_ARRAYBUFFER) { uint32_t bytesRead = 0; - aInputStream->Read((char*)JS_GetArrayBufferData(mResultArrayBuffer, NULL) + aOffset, + aInputStream->Read((char*)JS_GetArrayBufferData(mResultArrayBuffer) + aOffset, aCount, &bytesRead); NS_ASSERTION(bytesRead == aCount, "failed to read data"); } else { //Update memory buffer to reflect the contents of the file if (aOffset + aCount > UINT32_MAX) { // PR_Realloc doesn't support over 4GB memory size even if 64-bit OS return NS_ERROR_OUT_OF_MEMORY;
--- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -2664,18 +2664,18 @@ GetRequestBody(nsIVariant* aBody, nsIInp return NS_ERROR_FAILURE; } } nsresult rv = aBody->GetAsJSVal(&realVal); if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal)) { JSObject *obj = JSVAL_TO_OBJECT(realVal); ac.construct(cx, obj); - if (JS_IsArrayBufferObject(obj, cx)) { - ArrayBuffer buf(cx, obj); + if (JS_IsArrayBufferObject(obj)) { + ArrayBuffer buf(obj); return GetRequestBody(&buf, aResult, aContentLength, aContentType, aCharset); } } } else if (dataType == nsIDataType::VTYPE_VOID || dataType == nsIDataType::VTYPE_EMPTY) { // Makes us act as if !aBody, don't upload anything aContentType.AssignLiteral("text/plain");
--- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -4316,17 +4316,17 @@ CanvasRenderingContext2D::GetImageDataAr return NS_ERROR_OUT_OF_MEMORY; } if (mZero) { *aRetval = darray; return NS_OK; } - uint8_t* data = JS_GetUint8ClampedArrayData(darray, aCx); + uint8_t* data = JS_GetUint8ClampedArrayData(darray); IntRect srcRect(0, 0, mWidth, mHeight); IntRect destRect(aX, aY, aWidth, aHeight); IntRect srcReadRect = srcRect.Intersect(destRect); IntRect dstWriteRect = srcReadRect; dstWriteRect.MoveBy(-aX, -aY); @@ -4428,17 +4428,17 @@ CanvasRenderingContext2D::PutImageData(J ImageData& imageData, double dx, double dy, ErrorResult& error) { if (!FloatValidate(dx, dy)) { error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return; } - dom::Uint8ClampedArray arr(cx, imageData.GetDataObject()); + dom::Uint8ClampedArray arr(imageData.GetDataObject()); error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy), imageData.Width(), imageData.Height(), arr.Data(), arr.Length(), false, 0, 0, 0, 0); } void CanvasRenderingContext2D::PutImageData(JSContext* cx, @@ -4448,17 +4448,17 @@ CanvasRenderingContext2D::PutImageData(J double dirtyHeight, ErrorResult& error) { if (!FloatValidate(dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)) { error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return; } - dom::Uint8ClampedArray arr(cx, imageData.GetDataObject()); + dom::Uint8ClampedArray arr(imageData.GetDataObject()); error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy), imageData.Width(), imageData.Height(), arr.Data(), arr.Length(), true, JS_DoubleToInt32(dirtyX), JS_DoubleToInt32(dirtyY), JS_DoubleToInt32(dirtyWidth), JS_DoubleToInt32(dirtyHeight));
--- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -3152,18 +3152,18 @@ WebGLContext::ReadPixels(WebGLint x, Web if (!pixels) return ErrorInvalidValue("readPixels: null destination buffer"); const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject(); WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0; WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0; void* data = pixels->Data(); - uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj(), NULL); - int dataType = JS_GetTypedArrayType(pixels->Obj(), NULL); + uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj()); + int dataType = JS_GetTypedArrayType(pixels->Obj()); uint32_t channels = 0; // Check the format param switch (format) { case LOCAL_GL_ALPHA: channels = 1; break; @@ -4868,34 +4868,34 @@ WebGLContext::TexImage2D(JSContext* cx, WebGLenum type, ArrayBufferView *pixels, ErrorResult& rv) { if (!IsContextStable()) return; return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type, pixels ? pixels->Data() : 0, pixels ? pixels->Length() : 0, - pixels ? (int)JS_GetTypedArrayType(pixels->Obj(), cx) : -1, + pixels ? (int)JS_GetTypedArrayType(pixels->Obj()) : -1, WebGLTexelConversions::Auto, false); } void WebGLContext::TexImage2D(JSContext* cx, WebGLenum target, WebGLint level, WebGLenum internalformat, WebGLenum format, WebGLenum type, ImageData* pixels, ErrorResult& rv) { if (!IsContextStable()) return; if (!pixels) { // Spec says to generate an INVALID_VALUE error return ErrorInvalidValue("texImage2D: null ImageData"); } - Uint8ClampedArray arr(cx, pixels->GetDataObject()); + Uint8ClampedArray arr(pixels->GetDataObject()); return TexImage2D_base(target, level, internalformat, pixels->Width(), pixels->Height(), 4*pixels->Width(), 0, format, type, arr.Data(), arr.Length(), -1, WebGLTexelConversions::RGBA8, false); } void @@ -5022,33 +5022,33 @@ WebGLContext::TexSubImage2D(JSContext* c return; if (!pixels) return ErrorInvalidValue("texSubImage2D: pixels must not be null!"); return TexSubImage2D_base(target, level, xoffset, yoffset, width, height, 0, format, type, pixels->Data(), pixels->Length(), - JS_GetTypedArrayType(pixels->Obj(), cx), + JS_GetTypedArrayType(pixels->Obj()), WebGLTexelConversions::Auto, false); } void WebGLContext::TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level, WebGLint xoffset, WebGLint yoffset, WebGLenum format, WebGLenum type, ImageData* pixels, ErrorResult& rv) { if (!IsContextStable()) return; if (!pixels) return ErrorInvalidValue("texSubImage2D: pixels must not be null!"); - Uint8ClampedArray arr(cx, pixels->GetDataObject()); + Uint8ClampedArray arr(pixels->GetDataObject()); return TexSubImage2D_base(target, level, xoffset, yoffset, pixels->Width(), pixels->Height(), 4*pixels->Width(), format, type, arr.Data(), arr.Length(), -1, WebGLTexelConversions::RGBA8, false); }
--- a/content/events/src/nsDOMNotifyAudioAvailableEvent.cpp +++ b/content/events/src/nsDOMNotifyAudioAvailableEvent.cpp @@ -81,17 +81,17 @@ nsDOMNotifyAudioAvailableEvent::GetFrame // Cache this array so we don't recreate on next call. NS_HOLD_JS_OBJECTS(this, nsDOMNotifyAudioAvailableEvent); mCachedArray = JS_NewFloat32Array(aCx, mFrameBufferLength); if (!mCachedArray) { NS_DROP_JS_OBJECTS(this, nsDOMNotifyAudioAvailableEvent); 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); return NS_OK; } NS_IMETHODIMP nsDOMNotifyAudioAvailableEvent::GetTime(float *aRetVal) {
--- a/content/html/content/src/nsHTMLAudioElement.cpp +++ b/content/html/content/src/nsHTMLAudioElement.cpp @@ -151,41 +151,41 @@ nsHTMLAudioElement::MozWriteAudio(const return NS_ERROR_DOM_TYPE_MISMATCH_ERR; } JSObject* darray = &aData.toObject(); JS::AutoObjectRooter tvr(aCx); JSObject* tsrc = NULL; // Allow either Float32Array or plain JS Array - if (JS_IsFloat32Array(darray, aCx)) { + if (JS_IsFloat32Array(darray)) { tsrc = darray; } else if (JS_IsArrayObject(aCx, darray)) { JSObject* nobj = JS_NewFloat32ArrayFromArray(aCx, darray); if (!nobj) { return NS_ERROR_DOM_TYPE_MISMATCH_ERR; } tsrc = nobj; } else { return NS_ERROR_DOM_TYPE_MISMATCH_ERR; } 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 // on number of channels. if (dataLength % mChannels != 0) { return NS_ERROR_DOM_INDEX_SIZE_ERR; } // Don't write more than can be written without blocking. 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 // the nsAudioStream. // This could be optimized to avoid allocation and memcpy when // AudioDataValue is 'float', but it's not worth it for this deprecated API. nsAutoArrayPtr<AudioDataValue> audioData(new AudioDataValue[writeLen * mChannels]); ConvertAudioSamples(frames, audioData.get(), writeLen * mChannels); nsresult rv = mAudioStream->Write(audioData.get(), writeLen);
--- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -517,19 +517,21 @@ QueryInterface(JSContext* cx, unsigned a { JS::Value thisv = JS_THIS(cx, vp); if (thisv == JSVAL_NULL) return false; // Get the object. It might be a security wrapper, in which case we do a checked // unwrap. JSObject* origObj = JSVAL_TO_OBJECT(thisv); - JSObject* obj = js::UnwrapObjectChecked(cx, origObj); - if (!obj) + JSObject* obj = js::UnwrapObjectChecked(origObj); + if (!obj) { + JS_ReportError(cx, "Permission denied to access object"); return false; + } nsISupports* native; if (!UnwrapDOMObjectToISupports(obj, native)) { return Throw<true>(cx, NS_ERROR_FAILURE); } if (argc < 1) { return Throw<true>(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
--- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -240,17 +240,17 @@ IsArrayLike(JSContext* cx, JSObject* obj return false; } ac.construct(cx, obj); } // XXXbz need to detect platform objects (including listbinding // ones) with indexGetters here! - return JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj, cx); + return JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj); } inline bool IsPlatformObject(JSContext* cx, JSObject* obj) { // XXXbz Should be treating list-binding objects as platform objects // too? The one consumer so far wants non-array-like platform // objects, so listbindings that have an indexGetter should test @@ -267,17 +267,17 @@ IsPlatformObject(JSContext* cx, JSObject obj = xpc::Unwrap(cx, obj, false); if (!obj) { // Let's say it's not return false; } clasp = js::GetObjectJSClass(obj); } 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>). template <class T, typename U> inline nsresult UnwrapObject(JSContext* cx, JSObject* obj, U& value) { return UnwrapObject<static_cast<prototypes::ID>( @@ -1309,16 +1309,21 @@ public: bool WasPassed() const { return !mImpl.empty(); } void Construct() { mImpl.construct(); } + template <class T1> + void Construct(const T1 &t1) { + mImpl.construct(t1); + } + template <class T1, class T2> void Construct(const T1 &t1, const T2 &t2) { mImpl.construct(t1, t2); } const T& Value() const { return mImpl.ref(); }
--- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -2585,17 +2585,17 @@ for (uint32_t i = 0; i < length; ++i) { # We don't need a holder in this case holderType = None constructLoc = "(const_cast<Optional<" + name + ">& >(${declName}))" constructMethod = "Construct" constructInternal = "Value" else: declType = "NonNull<" + name + ">" template = ( - "%s.%s(cx, &${val}.toObject());\n" + "%s.%s(&${val}.toObject());\n" "if (!%s.%s().inited()) {\n" "%s" # No newline here because onFailureBadType() handles that "}\n" % (constructLoc, constructMethod, constructLoc, constructInternal, CGIndenter(onFailureBadType(failureCode, type.name)).define())) nullableTarget = "" if type.nullable(): if isOptional:
--- a/dom/bindings/TypedArray.h +++ b/dom/bindings/TypedArray.h @@ -14,21 +14,21 @@ namespace dom { /* * Various typed array classes for argument conversion. We have a base class * that has a way of initializing a TypedArray from an existing typed array, and * a subclass of the base class that supports creation of a relevant typed array * or array buffer object. */ template<typename T, - JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**)> + JSObject* UnboxArray(JSObject*, uint32_t*, T**)> 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: T* mData; uint32_t mLength; JSObject* mObj; public: @@ -49,38 +49,38 @@ public: inline JSObject *Obj() const { MOZ_ASSERT(inited()); return mObj; } }; template<typename T, - T* GetData(JSObject*, JSContext*), - JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**), + T* GetData(JSObject*), + JSObject* UnboxArray(JSObject*, uint32_t*, T**), JSObject* CreateNew(JSContext*, uint32_t)> struct TypedArray : public TypedArray_base<T,UnboxArray> { - TypedArray(JSContext* cx, JSObject* obj) : - TypedArray_base<T,UnboxArray>(cx, obj) + TypedArray(JSObject* obj) : + TypedArray_base<T,UnboxArray>(obj) {} static inline JSObject* Create(JSContext* cx, nsWrapperCache* creator, uint32_t length, const T* data = NULL) { JSObject* creatorWrapper; Maybe<JSAutoCompartment> ac; if (creator && (creatorWrapper = creator->GetWrapperPreserveColor())) { ac.construct(cx, creatorWrapper); } JSObject* obj = CreateNew(cx, length); if (!obj) { return NULL; } if (data) { - T* buf = static_cast<T*>(GetData(obj, cx)); + T* buf = static_cast<T*>(GetData(obj)); memcpy(buf, data, length*sizeof(T)); } return obj; } }; typedef TypedArray<int8_t, JS_GetInt8ArrayData, JS_GetObjectAsInt8Array, JS_NewInt8Array>
--- a/dom/file/LockedFile.cpp +++ b/dom/file/LockedFile.cpp @@ -213,19 +213,19 @@ CreateGenericEvent(const nsAString& aTyp inline nsresult GetInputStreamForJSVal(const jsval& aValue, JSContext* aCx, nsIInputStream** aInputStream, uint64_t* aInputLength) { nsresult rv; if (!JSVAL_IS_PRIMITIVE(aValue)) { JSObject* obj = JSVAL_TO_OBJECT(aValue); - if (JS_IsArrayBufferObject(obj, aCx)) { - char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj, aCx)); - uint32_t length = JS_GetArrayBufferByteLength(obj, aCx); + if (JS_IsArrayBufferObject(obj)) { + char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj)); + uint32_t length = JS_GetArrayBufferByteLength(obj); rv = NS_NewByteInputStream(aInputStream, data, length, NS_ASSIGNMENT_COPY); NS_ENSURE_SUCCESS(rv, rv); *aInputLength = length; return NS_OK;
--- a/dom/network/src/TCPSocketChild.cpp +++ b/dom/network/src/TCPSocketChild.cpp @@ -23,17 +23,17 @@ DeserializeUint8Array(JSRawObject aObj, { JSContext* cx = nsContentUtils::GetSafeJSContext(); JSAutoRequest ar(cx); JSAutoCompartment ac(cx, aObj); JSObject* obj = JS_NewArrayBuffer(cx, aBuffer.Length()); if (!obj) return false; - uint8_t* data = JS_GetArrayBufferData(obj, cx); + uint8_t* data = JS_GetArrayBufferData(obj); if (!data) return false; memcpy(data, aBuffer.Elements(), aBuffer.Length()); JSObject* arr = JS_NewUint8ArrayWithBuffer(cx, obj, 0, aBuffer.Length()); if (!arr) return false; *aVal = OBJECT_TO_JSVAL(arr); return true; @@ -182,20 +182,20 @@ TCPSocketChild::Send(const JS::Value& aD nsDependentJSString str; bool ok = str.init(aCx, jsstr); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); SendData(str); } else { NS_ENSURE_TRUE(aData.isObject(), NS_ERROR_FAILURE); JSObject* obj = &aData.toObject(); - NS_ENSURE_TRUE(JS_IsTypedArrayObject(obj, aCx), NS_ERROR_FAILURE); - NS_ENSURE_TRUE(JS_IsUint8Array(obj, aCx), NS_ERROR_FAILURE); - uint32_t nbytes = JS_GetTypedArrayByteLength(obj, aCx); - uint8_t* data = JS_GetUint8ArrayData(obj, aCx); + NS_ENSURE_TRUE(JS_IsTypedArrayObject(obj), NS_ERROR_FAILURE); + NS_ENSURE_TRUE(JS_IsUint8Array(obj), NS_ERROR_FAILURE); + uint32_t nbytes = JS_GetTypedArrayByteLength(obj); + uint8_t* data = JS_GetUint8ArrayData(obj); if (!data) { return NS_ERROR_OUT_OF_MEMORY; } FallibleTArray<uint8_t> fallibleArr; if (!fallibleArr.InsertElementsAt(0, data, nbytes)) { return NS_ERROR_OUT_OF_MEMORY; } InfallibleTArray<uint8_t> arr;
--- a/dom/network/src/TCPSocketParent.cpp +++ b/dom/network/src/TCPSocketParent.cpp @@ -151,20 +151,20 @@ TCPSocketParent::SendCallback(const nsAS } data = str; } else if (aDataVal.isUndefined() || aDataVal.isNull()) { data = mozilla::void_t(); } else if (aDataVal.isObject()) { JSObject* obj = &aDataVal.toObject(); - if (JS_IsTypedArrayObject(obj, aCx)) { - NS_ENSURE_TRUE(JS_IsUint8Array(obj, aCx), NS_ERROR_FAILURE); - uint32_t nbytes = JS_GetTypedArrayByteLength(obj, aCx); - uint8_t* buffer = JS_GetUint8ArrayData(obj, aCx); + if (JS_IsTypedArrayObject(obj)) { + NS_ENSURE_TRUE(JS_IsUint8Array(obj), NS_ERROR_FAILURE); + uint32_t nbytes = JS_GetTypedArrayByteLength(obj); + uint8_t* buffer = JS_GetUint8ArrayData(obj); if (!buffer) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } FallibleTArray<uint8_t> fallibleArr; if (!fallibleArr.InsertElementsAt(0, buffer, nbytes)) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY;
--- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -455,30 +455,22 @@ JSValToNPVariant(NPP npp, JSContext *cx, return true; } // The reflected plugin object may be in another compartment if the plugin // element has since been adopted into a new document. We don't bother // 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, - // we clear the pending exception and just run with the original wrapped object, - // since sometimes there are legitimate cases where a security wrapper ends - // up here (for example, Location objects, which are _always_ behind security - // 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. + // we run with the original wrapped object, since sometimes there are + // legitimate cases where a security wrapper ends up here (for example, + // Location objects, which are _always_ behind security wrappers). JSObject *obj = JSVAL_TO_OBJECT(val); - JSErrorReporter reporter = JS_SetErrorReporter(cx, NULL); - obj = js::UnwrapObjectChecked(cx, obj); - JS_SetErrorReporter(cx, reporter); + obj = js::UnwrapObjectChecked(obj); if (!obj) { - JS_ClearPendingException(cx); obj = JSVAL_TO_OBJECT(val); } NPObject *npobj = nsJSObjWrapper::GetNewOrUsed(npp, cx, obj); if (!npobj) { return false; } @@ -1129,17 +1121,17 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS // wrapper. // // Because this function unwraps, its return value must be wrapped for the cx // compartment for callers that plan to hold onto the result or do anything // substantial with it. static JSObject * 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 (wrapResult && !JS_WrapObject(cx, &obj)) { return NULL; } return obj; } if (!::JS_GetPrototype(cx, obj, &obj)) { return NULL;
--- a/dom/system/gonk/SystemWorkerManager.cpp +++ b/dom/system/gonk/SystemWorkerManager.cpp @@ -84,31 +84,31 @@ PostToRIL(JSContext *cx, unsigned argc, if (!abs.encode(cx, str)) { return false; } size = JS_GetStringLength(str); data = abs.ptr(); } else if (!JSVAL_IS_PRIMITIVE(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"); return false; } - uint32_t type = JS_GetTypedArrayType(obj, cx); + uint32_t type = JS_GetTypedArrayType(obj); if (type != js::ArrayBufferView::TYPE_INT8 && type != js::ArrayBufferView::TYPE_UINT8 && type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) { JS_ReportError(cx, "Typed array data is not octets"); return false; } - size = JS_GetTypedArrayByteLength(obj, cx); - data = JS_GetArrayBufferViewData(obj, cx); + size = JS_GetTypedArrayByteLength(obj); + data = JS_GetArrayBufferViewData(obj); } else { JS_ReportError(cx, "Incorrect argument. Expecting a string or a typed array"); return false; } if (size > RilRawData::MAX_DATA_SIZE) { JS_ReportError(cx, "Passed-in data is too large"); @@ -170,17 +170,17 @@ RILReceiver::DispatchRILEvent::RunTask(J { JSObject *obj = JS_GetGlobalObject(aCx); JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize); if (!array) { 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) }; return JS_CallFunctionName(aCx, obj, "onRILMessage", NS_ARRAY_LENGTH(argv), argv, argv); } #ifdef MOZ_WIDGET_GONK JSBool @@ -212,36 +212,36 @@ DoNetdCommand(JSContext *cx, unsigned ar data = abs.ptr(); if (!data) { JS_ReportError(cx, "Command string is empty"); return false; } } else if (!JSVAL_IS_PRIMITIVE(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"); return false; } - uint32_t type = JS_GetTypedArrayType(obj, cx); + uint32_t type = JS_GetTypedArrayType(obj); if (type != js::ArrayBufferView::TYPE_INT8 && type != js::ArrayBufferView::TYPE_UINT8 && type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) { JS_ReportError(cx, "Typed array data is not octets"); return false; } - size = JS_GetTypedArrayByteLength(obj, cx); + size = JS_GetTypedArrayByteLength(obj); if (!size) { JS_ReportError(cx, "Typed array byte length is zero"); return false; } - data = JS_GetArrayBufferViewData(obj, cx); + data = JS_GetArrayBufferViewData(obj); if (!data) { JS_ReportError(cx, "Array buffer view data is NULL"); return false; } } else { JS_ReportError(cx, "Incorrect argument. Expecting a string or a typed array"); return false; @@ -317,17 +317,17 @@ NetdReceiver::DispatchNetdEvent::RunTask { JSObject *obj = JS_GetGlobalObject(aCx); JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize); if (!array) { 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) }; return JS_CallFunctionName(aCx, obj, "onNetdMessage", NS_ARRAY_LENGTH(argv), argv, argv); } #endif // MOZ_WIDGET_GONK } // anonymous namespace
--- a/dom/workers/FileReaderSync.cpp +++ b/dom/workers/FileReaderSync.cpp @@ -90,18 +90,18 @@ FileReaderSync::ReadAsArrayBuffer(JSCont JSObject* jsArrayBuffer = JS_NewArrayBuffer(aCx, blobSize); if (!jsArrayBuffer) { // XXXkhuey we need a way to indicate to the bindings that the call failed // but there's already a pending exception that we should not clobber. aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; } - uint32_t bufferLength = JS_GetArrayBufferByteLength(jsArrayBuffer, aCx); - uint8_t* arrayBuffer = JS_GetArrayBufferData(jsArrayBuffer, aCx); + uint32_t bufferLength = JS_GetArrayBufferByteLength(jsArrayBuffer); + uint8_t* arrayBuffer = JS_GetArrayBufferData(jsArrayBuffer); nsCOMPtr<nsIInputStream> stream; rv = blob->GetInternalStream(getter_AddRefs(stream)); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; }
--- a/dom/workers/ImageData.cpp +++ b/dom/workers/ImageData.cpp @@ -35,18 +35,18 @@ public: return JS_InitClass(aCx, aObj, NULL, &sClass, Construct, 0, sProperties, NULL, NULL, NULL); } static JSObject* Create(JSContext* aCx, uint32_t aWidth, uint32_t aHeight, JSObject *aData) { MOZ_ASSERT(aData); - MOZ_ASSERT(JS_IsTypedArrayObject(aData, aCx)); - MOZ_ASSERT(JS_IsUint8ClampedArray(aData, aCx)); + MOZ_ASSERT(JS_IsTypedArrayObject(aData)); + MOZ_ASSERT(JS_IsUint8ClampedArray(aData)); JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL); if (!obj) { return NULL; } JS_SetReservedSlot(obj, SLOT_width, UINT_TO_JSVAL(aWidth)); JS_SetReservedSlot(obj, SLOT_height, UINT_TO_JSVAL(aHeight));
--- a/dom/workers/XMLHttpRequest.cpp +++ b/dom/workers/XMLHttpRequest.cpp @@ -2003,17 +2003,17 @@ XMLHttpRequest::Send(JSObject* aBody, Er if (!mProxy) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } JSContext* cx = GetJSContext(); jsval valToClone; - if (JS_IsArrayBufferObject(aBody, cx) || file::GetDOMBlobFromJSObject(aBody)) { + if (JS_IsArrayBufferObject(aBody) || file::GetDOMBlobFromJSObject(aBody)) { valToClone = OBJECT_TO_JSVAL(aBody); } else { JSString* bodyStr = JS_ValueToString(cx, OBJECT_TO_JSVAL(aBody)); if (!bodyStr) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; }
--- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -2111,17 +2111,17 @@ ConvertToJS(JSContext* cx, // ambiguity to a C type. Elements of a Int8Array are converted to // ctypes.int8_t, UInt8Array to ctypes.uint8_t, etc. bool CanConvertTypedArrayItemTo(JSObject *baseType, JSObject *valObj, JSContext *cx) { TypeCode baseTypeCode = CType::GetTypeCode(baseType); if (baseTypeCode == TYPE_void_t) { return true; } TypeCode elementTypeCode; - switch (JS_GetTypedArrayType(valObj, cx)) { + switch (JS_GetTypedArrayType(valObj)) { case TypedArray::TYPE_INT8: elementTypeCode = TYPE_int8_t; break; case TypedArray::TYPE_UINT8: case TypedArray::TYPE_UINT8_CLAMPED: elementTypeCode = TYPE_uint8_t; break; case TypedArray::TYPE_INT16: @@ -2336,31 +2336,31 @@ ImplicitConvert(JSContext* cx, memcpy(*jscharBuffer, sourceChars, sourceLength * sizeof(jschar)); (*jscharBuffer)[sourceLength] = 0; break; } default: return TypeError(cx, "string pointer", val); } 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. // Just as with C arrays, we make no effort to // keep the ArrayBuffer alive. - *static_cast<void**>(buffer) = JS_GetArrayBufferData(valObj, cx); + *static_cast<void**>(buffer) = JS_GetArrayBufferData(valObj); break; - } if (!JSVAL_IS_PRIMITIVE(val) && JS_IsTypedArrayObject(valObj, cx)) { + } if (!JSVAL_IS_PRIMITIVE(val) && JS_IsTypedArrayObject(valObj)) { if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) { return TypeError(cx, "typed array with the appropriate type", val); } // Convert TypedArray to pointer without any copy. // Just as with C arrays, we make no effort to // keep the TypedArray alive. - *static_cast<void**>(buffer) = JS_GetArrayBufferViewData(valObj, cx); + *static_cast<void**>(buffer) = JS_GetArrayBufferViewData(valObj); break; } return TypeError(cx, "pointer", val); } case TYPE_array: { JSObject* baseType = ArrayType::GetBaseType(targetType); size_t targetLength = ArrayType::GetLength(targetType); @@ -2439,44 +2439,44 @@ ImplicitConvert(JSContext* cx, char* data = intermediate.get() + elementSize * i; if (!ImplicitConvert(cx, item.jsval_value(), baseType, data, false, NULL)) return false; } memcpy(buffer, intermediate.get(), arraySize); } else if (!JSVAL_IS_PRIMITIVE(val) && - JS_IsArrayBufferObject(valObj, cx)) { + JS_IsArrayBufferObject(valObj)) { // Check that array is consistent with type, then // copy the array. - uint32_t sourceLength = JS_GetArrayBufferByteLength(valObj, cx); + uint32_t sourceLength = JS_GetArrayBufferByteLength(valObj); size_t elementSize = CType::GetSize(baseType); size_t arraySize = elementSize * targetLength; if (arraySize != size_t(sourceLength)) { JS_ReportError(cx, "ArrayType length does not match source ArrayBuffer length"); return false; } - memcpy(buffer, JS_GetArrayBufferData(valObj, cx), sourceLength); + memcpy(buffer, JS_GetArrayBufferData(valObj), sourceLength); break; } else if (!JSVAL_IS_PRIMITIVE(val) && - JS_IsTypedArrayObject(valObj, cx)) { + JS_IsTypedArrayObject(valObj)) { // Check that array is consistent with type, then // copy the array. if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) { 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 arraySize = elementSize * targetLength; if (arraySize != size_t(sourceLength)) { JS_ReportError(cx, "typed array length does not match source TypedArray length"); return false; } - memcpy(buffer, JS_GetArrayBufferViewData(valObj, cx), sourceLength); + memcpy(buffer, JS_GetArrayBufferViewData(valObj), sourceLength); break; } else { // Don't implicitly convert to string. Users can implicitly convert // with `String(x)` or `""+x`. return TypeError(cx, "array", val); } break; }
--- a/js/src/jsapi-tests/testArrayBuffer.cpp +++ b/js/src/jsapi-tests/testArrayBuffer.cpp @@ -31,61 +31,61 @@ BEGIN_TEST(testArrayBuffer_bug720949_ste for (unsigned i = 0; i < NUM_TEST_BUFFERS; i++) { JS::HandleObject obj = testBuf[i]; JS::HandleObject view = testArray[i]; uint32_t size = sizes[i]; jsval v; // Byte lengths should all agree - CHECK(JS_IsArrayBufferObject(obj, cx)); - CHECK_EQUAL(JS_GetArrayBufferByteLength(obj, cx), size); + CHECK(JS_IsArrayBufferObject(obj)); + CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), size); JS_GetProperty(cx, obj, "byteLength", &v); CHECK_SAME(v, INT_TO_JSVAL(size)); JS_GetProperty(cx, view, "byteLength", &v); CHECK_SAME(v, INT_TO_JSVAL(size)); // 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); *reinterpret_cast<uint32_t*>(data) = MAGIC_VALUE_2; CHECK(JS_GetElement(cx, view, 0, &v)); CHECK_SAME(v, INT_TO_JSVAL(MAGIC_VALUE_2)); // Steal the contents void *contents; CHECK(JS_StealArrayBufferContents(cx, obj, &contents, &data)); CHECK(contents != NULL); CHECK(data != NULL); // 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_SAME(v, INT_TO_JSVAL(0)); CHECK(JS_GetProperty(cx, view, "byteLength", &v)); CHECK_SAME(v, INT_TO_JSVAL(0)); CHECK(JS_GetProperty(cx, view, "byteOffset", &v)); CHECK_SAME(v, INT_TO_JSVAL(0)); CHECK(JS_GetProperty(cx, view, "length", &v)); CHECK_SAME(v, INT_TO_JSVAL(0)); - CHECK_EQUAL(JS_GetArrayBufferByteLength(obj, cx), 0); + CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), 0); v = JSVAL_VOID; JS_GetElement(cx, obj, 0, &v); CHECK_SAME(v, JSVAL_VOID); // Transfer to a new ArrayBuffer js::RootedObject dst(cx, JS_NewArrayBufferWithContents(cx, contents)); - CHECK(JS_IsArrayBufferObject(dst, cx)); - data = JS_GetArrayBufferData(obj, cx); + CHECK(JS_IsArrayBufferObject(dst)); + data = JS_GetArrayBufferData(obj); js::RootedObject dstview(cx, JS_NewInt32ArrayWithBuffer(cx, dst, 0, -1)); CHECK(dstview != NULL); - CHECK_EQUAL(JS_GetArrayBufferByteLength(dst, cx), size); - data = JS_GetArrayBufferData(dst, cx); + CHECK_EQUAL(JS_GetArrayBufferByteLength(dst), size); + data = JS_GetArrayBufferData(dst); CHECK(data != NULL); CHECK_EQUAL(*reinterpret_cast<uint32_t*>(data), MAGIC_VALUE_2); CHECK(JS_GetElement(cx, dstview, 0, &v)); CHECK_SAME(v, INT_TO_JSVAL(MAGIC_VALUE_2)); } return true; }
--- a/js/src/jsapi-tests/testTypedArrays.cpp +++ b/js/src/jsapi-tests/testTypedArrays.cpp @@ -23,26 +23,26 @@ BEGIN_TEST(testTypedArrays) TestPlainTypedArray<JS_NewUint16Array, uint16_t, JS_GetUint16ArrayData>(cx) && TestPlainTypedArray<JS_NewInt32Array, int32_t, JS_GetInt32ArrayData>(cx) && TestPlainTypedArray<JS_NewUint32Array, uint32_t, JS_GetUint32ArrayData>(cx) && TestPlainTypedArray<JS_NewFloat32Array, float, JS_GetFloat32ArrayData>(cx) && TestPlainTypedArray<JS_NewFloat64Array, double, JS_GetFloat64ArrayData>(cx); size_t nbytes = sizeof(double) * 8; RootedObject buffer(cx, JS_NewArrayBuffer(cx, nbytes)); - CHECK(JS_IsArrayBufferObject(buffer, cx)); + CHECK(JS_IsArrayBufferObject(buffer)); RootedObject proto(cx); JS_GetPrototype(cx, buffer, proto.address()); - CHECK(!JS_IsArrayBufferObject(proto, cx)); + CHECK(!JS_IsArrayBufferObject(proto)); RootedObject dummy(cx, JS_GetParent(proto)); - CHECK(!JS_IsArrayBufferObject(dummy, cx)); + CHECK(!JS_IsArrayBufferObject(dummy)); - CHECK_EQUAL(JS_GetArrayBufferByteLength(buffer, cx), nbytes); - memset(JS_GetArrayBufferData(buffer, cx), 1, nbytes); + CHECK_EQUAL(JS_GetArrayBufferByteLength(buffer), nbytes); + memset(JS_GetArrayBufferData(buffer), 1, nbytes); ok = ok && TestArrayFromBuffer<JS_NewInt8ArrayWithBuffer, JS_NewInt8ArrayFromArray, int8_t, JS_GetInt8ArrayData>(cx) && TestArrayFromBuffer<JS_NewUint8ArrayWithBuffer, JS_NewUint8ArrayFromArray, uint8_t, JS_GetUint8ArrayData>(cx) && TestArrayFromBuffer<JS_NewUint8ClampedArrayWithBuffer, JS_NewUint8ClampedArrayFromArray, uint8_t, JS_GetUint8ClampedArrayData>(cx) && TestArrayFromBuffer<JS_NewInt16ArrayWithBuffer, JS_NewInt16ArrayFromArray, int16_t, JS_GetInt16ArrayData>(cx) && TestArrayFromBuffer<JS_NewUint16ArrayWithBuffer, JS_NewUint16ArrayFromArray, uint16_t, JS_GetUint16ArrayData>(cx) && TestArrayFromBuffer<JS_NewInt32ArrayWithBuffer, JS_NewInt32ArrayFromArray, int32_t, JS_GetInt32ArrayData>(cx) && @@ -50,79 +50,79 @@ BEGIN_TEST(testTypedArrays) TestArrayFromBuffer<JS_NewFloat32ArrayWithBuffer, JS_NewFloat32ArrayFromArray, float, JS_GetFloat32ArrayData>(cx) && TestArrayFromBuffer<JS_NewFloat64ArrayWithBuffer, JS_NewFloat64ArrayFromArray, double, JS_GetFloat64ArrayData>(cx); return ok; } template<JSObject *Create(JSContext *, uint32_t), typename Element, - Element *GetData(JSObject *, JSContext *)> + Element *GetData(JSObject *)> bool TestPlainTypedArray(JSContext *cx) { RootedObject array(cx, Create(cx, 7)); - CHECK(JS_IsTypedArrayObject(array, cx)); + CHECK(JS_IsTypedArrayObject(array)); RootedObject proto(cx); JS_GetPrototype(cx, array, proto.address()); - CHECK(!JS_IsTypedArrayObject(proto, cx)); + CHECK(!JS_IsTypedArrayObject(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_GetTypedArrayByteOffset(array, cx), 0); - CHECK_EQUAL(JS_GetTypedArrayByteLength(array, cx), sizeof(Element) * 7); + CHECK_EQUAL(JS_GetTypedArrayLength(array), 7); + CHECK_EQUAL(JS_GetTypedArrayByteOffset(array), 0); + CHECK_EQUAL(JS_GetTypedArrayByteLength(array), sizeof(Element) * 7); Element *data; - CHECK(data = GetData(array, cx)); + CHECK(data = GetData(array)); *data = 13; jsval v; CHECK(JS_GetElement(cx, array, 0, &v)); CHECK_SAME(v, INT_TO_JSVAL(13)); return true; } template<JSObject *CreateWithBuffer(JSContext *, JSObject *, uint32_t, int32_t), JSObject *CreateFromArray(JSContext *, JSObject *), typename Element, - Element *GetData(JSObject *, JSContext *)> + Element *GetData(JSObject *)> bool TestArrayFromBuffer(JSContext *cx) { size_t elts = 8; size_t nbytes = elts * sizeof(Element); RootedObject buffer(cx, JS_NewArrayBuffer(cx, nbytes)); uint8_t *bufdata; - CHECK(bufdata = JS_GetArrayBufferData(buffer, cx)); + CHECK(bufdata = JS_GetArrayBufferData(buffer)); memset(bufdata, 1, nbytes); RootedObject array(cx, CreateWithBuffer(cx, buffer, 0, -1)); - CHECK_EQUAL(JS_GetTypedArrayLength(array, cx), elts); - CHECK_EQUAL(JS_GetTypedArrayByteOffset(array, cx), 0); - CHECK_EQUAL(JS_GetTypedArrayByteLength(array, cx), nbytes); - CHECK_EQUAL(JS_GetArrayBufferViewBuffer(array, cx), (JSObject*) buffer); + CHECK_EQUAL(JS_GetTypedArrayLength(array), elts); + CHECK_EQUAL(JS_GetTypedArrayByteOffset(array), 0); + CHECK_EQUAL(JS_GetTypedArrayByteLength(array), nbytes); + CHECK_EQUAL(JS_GetArrayBufferViewBuffer(array), (JSObject*) buffer); Element *data; - CHECK(data = GetData(array, cx)); - CHECK(bufdata = JS_GetArrayBufferData(buffer, cx)); + CHECK(data = GetData(array)); + CHECK(bufdata = JS_GetArrayBufferData(buffer)); CHECK_EQUAL((void*) data, (void*) bufdata); CHECK_EQUAL(*bufdata, 1); CHECK_EQUAL(*reinterpret_cast<uint8_t*>(data), 1); RootedObject shortArray(cx, CreateWithBuffer(cx, buffer, 0, elts / 2)); - CHECK_EQUAL(JS_GetTypedArrayLength(shortArray, cx), elts / 2); - CHECK_EQUAL(JS_GetTypedArrayByteOffset(shortArray, cx), 0); - CHECK_EQUAL(JS_GetTypedArrayByteLength(shortArray, cx), nbytes / 2); + CHECK_EQUAL(JS_GetTypedArrayLength(shortArray), elts / 2); + CHECK_EQUAL(JS_GetTypedArrayByteOffset(shortArray), 0); + CHECK_EQUAL(JS_GetTypedArrayByteLength(shortArray), nbytes / 2); RootedObject ofsArray(cx, CreateWithBuffer(cx, buffer, nbytes / 2, -1)); - CHECK_EQUAL(JS_GetTypedArrayLength(ofsArray, cx), elts / 2); - CHECK_EQUAL(JS_GetTypedArrayByteOffset(ofsArray, cx), nbytes / 2); - CHECK_EQUAL(JS_GetTypedArrayByteLength(ofsArray, cx), nbytes / 2); + CHECK_EQUAL(JS_GetTypedArrayLength(ofsArray), elts / 2); + CHECK_EQUAL(JS_GetTypedArrayByteOffset(ofsArray), nbytes / 2); + CHECK_EQUAL(JS_GetTypedArrayByteLength(ofsArray), nbytes / 2); // Make sure all 3 views reflect the same buffer at the expected locations jsval v = INT_TO_JSVAL(39); JS_SetElement(cx, array, 0, &v); jsval v2; CHECK(JS_GetElement(cx, array, 0, &v2)); CHECK_SAME(v, v2); CHECK(JS_GetElement(cx, shortArray, 0, &v2));
--- a/js/src/jsclone.cpp +++ b/js/src/jsclone.cpp @@ -562,23 +562,23 @@ JSStructuredCloneWriter::checkStack() } JS_PUBLIC_API(JSBool) JS_WriteTypedArray(JSStructuredCloneWriter *w, jsval v) { JS_ASSERT(v.isObject()); RootedObject obj(w->context(), &v.toObject()); - // If the object is a security wrapper, try puncturing it. This may throw - // if the access is not allowed. - if (obj->isWrapper()) { - JSObject *unwrapped = UnwrapObjectChecked(w->context(), obj); - if (!unwrapped) - return false; - obj = unwrapped; + // If the object is a security wrapper, see if we're allowed to unwrap it. + // If we aren't, throw. + if (obj->isWrapper()) + obj = UnwrapObjectChecked(obj); + if (!obj) { + JS_ReportError(w->context(), "Permission denied to access object"); + return false; } return w->writeTypedArray(obj); } bool JSStructuredCloneWriter::writeTypedArray(HandleObject arr) { if (!out.writePair(ArrayTypeToTag(TypedArray::type(arr)), TypedArray::length(arr))) @@ -669,19 +669,21 @@ JSStructuredCloneWriter::startWrite(cons return out.writePair(SCTAG_NULL, 0); } else if (v.isUndefined()) { return out.writePair(SCTAG_UNDEFINED, 0); } else if (v.isObject()) { RootedObject obj(context(), &v.toObject()); // The object might be a security wrapper. See if we can clone what's // behind it. If we can, unwrap the object. - obj = UnwrapObjectChecked(context(), obj); - if (!obj) + obj = UnwrapObjectChecked(obj); + if (!obj) { + JS_ReportError(context(), "Permission denied to access object"); return false; + } AutoCompartment ac(context(), obj); bool backref; if (!startObject(obj, &backref)) return false; if (backref) return true; @@ -892,33 +894,33 @@ JSStructuredCloneReader::readTypedArray( if (!obj) return false; vp->setObject(*obj); JS_ASSERT(TypedArray::length(obj) == nelems); switch (tag) { 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: - return in.readArray(JS_GetUint8ArrayData(obj, context()), nelems); + return in.readArray(JS_GetUint8ArrayData(obj), nelems); 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: - return in.readArray(JS_GetUint16ArrayData(obj, context()), nelems); + return in.readArray(JS_GetUint16ArrayData(obj), nelems); 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: - return in.readArray(JS_GetUint32ArrayData(obj, context()), nelems); + return in.readArray(JS_GetUint32ArrayData(obj), nelems); 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: - 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: - return in.readArray(JS_GetUint8ClampedArrayData(obj, context()), nelems); + return in.readArray(JS_GetUint8ClampedArrayData(obj), nelems); default: JS_NOT_REACHED("unknown TypedArray type"); return false; } } bool JSStructuredCloneReader::readArrayBuffer(uint32_t nbytes, Value *vp)
--- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -1178,258 +1178,247 @@ JS_NewArrayBuffer(JSContext *cx, uint32_ /* * Check whether obj supports JS_GetTypedArray* APIs. Note that this may return * false if a security wrapper is encountered that denies the unwrapping. If * this test or one of the JS_Is*Array tests succeeds, then it is safe to call * the various accessor JSAPI calls defined below. */ 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 * 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 * 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) -JS_IsArrayBufferViewObject(JSObject *obj, JSContext *cx); +JS_IsArrayBufferViewObject(JSObject *obj); /* * Test for specific typed array types (ArrayBufferView subtypes) */ extern JS_FRIEND_API(JSBool) -JS_IsInt8Array(JSObject *obj, JSContext *cx); +JS_IsInt8Array(JSObject *obj); extern JS_FRIEND_API(JSBool) -JS_IsUint8Array(JSObject *obj, JSContext *cx); +JS_IsUint8Array(JSObject *obj); extern JS_FRIEND_API(JSBool) -JS_IsUint8ClampedArray(JSObject *obj, JSContext *cx); +JS_IsUint8ClampedArray(JSObject *obj); extern JS_FRIEND_API(JSBool) -JS_IsInt16Array(JSObject *obj, JSContext *cx); +JS_IsInt16Array(JSObject *obj); extern JS_FRIEND_API(JSBool) -JS_IsUint16Array(JSObject *obj, JSContext *cx); +JS_IsUint16Array(JSObject *obj); extern JS_FRIEND_API(JSBool) -JS_IsInt32Array(JSObject *obj, JSContext *cx); +JS_IsInt32Array(JSObject *obj); extern JS_FRIEND_API(JSBool) -JS_IsUint32Array(JSObject *obj, JSContext *cx); +JS_IsUint32Array(JSObject *obj); extern JS_FRIEND_API(JSBool) -JS_IsFloat32Array(JSObject *obj, JSContext *cx); +JS_IsFloat32Array(JSObject *obj); 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 * cannot be viewed as the correct typed array, or the typed array object on * success, filling both outparameters. */ 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 *) -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 *) -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 *) -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 *) -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 *) -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 *) -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 *) -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 *) -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 *) -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 *) -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. * * |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 - * a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG - * builds may be unable to assert when unwrapping should be disallowed. + * a typed array, and the unwrapping will succeed. */ 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 * return false if a security wrapper is encountered that denies the * unwrapping. If this test succeeds, then it is safe to call the various * accessor JSAPI calls defined below. */ extern JS_FRIEND_API(JSBool) -JS_IsArrayBufferObject(JSObject *obj, JSContext *maybecx); +JS_IsArrayBufferObject(JSObject *obj); /* * Return the available byte length of an array buffer. * * |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 - * ArrayBuffer, and the unwrapping will succeed. If cx is NULL, then DEBUG - * builds may be unable to assert when unwrapping should be disallowed. + * ArrayBuffer, and the unwrapping will succeed. */ 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 * array buffer object, and should not be modified on another thread. The * returned pointer is stable across GCs. * * |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 - * ArrayBuffer, and the unwrapping will succeed. If cx is NULL, then DEBUG - * builds may be unable to assert when unwrapping should be disallowed. + * ArrayBuffer, and the unwrapping will succeed. */ 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. * * |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 - * a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG - * builds may be unable to assert when unwrapping should be disallowed. + * a typed array, and the unwrapping will succeed. */ 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 * typed array view. * * |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 - * a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG - * builds may be unable to assert when unwrapping should be disallowed. + * a typed array, and the unwrapping will succeed. */ extern JS_FRIEND_API(uint32_t) -JS_GetTypedArrayByteOffset(JSObject *obj, JSContext *cx); +JS_GetTypedArrayByteOffset(JSObject *obj); /* * Return the byte length of a typed array. * * |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 - * a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG - * builds may be unable to assert when unwrapping should be disallowed. + * a typed array, and the unwrapping will succeed. */ 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 * return false if a security wrapper is encountered that denies the * unwrapping. */ 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 */ 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 * data is still owned by the typed array, and should not be modified on * another thread. * * |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 - * unwrapping will succeed. If cx is NULL, then DEBUG builds may be unable to - * assert when unwrapping should be disallowed. + * unwrapping will succeed. */ extern JS_FRIEND_API(int8_t *) -JS_GetInt8ArrayData(JSObject *obj, JSContext *maybecx); +JS_GetInt8ArrayData(JSObject *obj); extern JS_FRIEND_API(uint8_t *) -JS_GetUint8ArrayData(JSObject *obj, JSContext *maybecx); +JS_GetUint8ArrayData(JSObject *obj); extern JS_FRIEND_API(uint8_t *) -JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *maybecx); +JS_GetUint8ClampedArrayData(JSObject *obj); extern JS_FRIEND_API(int16_t *) -JS_GetInt16ArrayData(JSObject *obj, JSContext *maybecx); +JS_GetInt16ArrayData(JSObject *obj); extern JS_FRIEND_API(uint16_t *) -JS_GetUint16ArrayData(JSObject *obj, JSContext *maybecx); +JS_GetUint16ArrayData(JSObject *obj); extern JS_FRIEND_API(int32_t *) -JS_GetInt32ArrayData(JSObject *obj, JSContext *maybecx); +JS_GetInt32ArrayData(JSObject *obj); extern JS_FRIEND_API(uint32_t *) -JS_GetUint32ArrayData(JSObject *obj, JSContext *maybecx); +JS_GetUint32ArrayData(JSObject *obj); extern JS_FRIEND_API(float *) -JS_GetFloat32ArrayData(JSObject *obj, JSContext *maybecx); +JS_GetFloat32ArrayData(JSObject *obj); 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 * versions when possible. */ 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 * neutered, this will still return the neutered buffer. |obj| must be an * object that would return true for JS_IsArrayBufferViewObject(). */ 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 - * throw an exception if a security wrapper is encountered that denies the - * operation. + * Check whether obj supports JS_GetDataView* APIs. */ 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 * DataView. * * |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, - * and the unwrapping will succeed. If cx is NULL, then DEBUG builds may be - * unable to assert when unwrapping should be disallowed. + * and the unwrapping will succeed. */ JS_FRIEND_API(uint32_t) -JS_GetDataViewByteOffset(JSObject *obj, JSContext *maybecx); +JS_GetDataViewByteOffset(JSObject *obj); /* * Return the byte length of a data view. * * |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, * and the unwrapping will succeed. If cx is NULL, then DEBUG builds may be * unable to assert when unwrapping should be disallowed. */ 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. * * |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, * and the unwrapping will succeed. If cx is NULL, then DEBUG builds may be * unable to assert when unwrapping should be disallowed. */ 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 * optimizations on DOM property accessors. Eventually, this should be made * available to general JSAPI users, but we are not currently ready to do so. */ typedef bool (* JSJitPropertyOp)(JSContext *cx, JSHandleObject thisObj,
--- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -169,26 +169,20 @@ fun_getProperty(JSContext *cx, HandleObj return true; } vp.set(iter.calleev()); if (!cx->compartment->wrap(cx, vp.address())) return false; /* - * Censor the caller if we can't PUNCTURE it. - * - * NB - This will get much much nicer with bug 800915 + * Censor the caller if we don't have full access to it. */ JSObject &caller = vp.toObject(); - JSErrorReporter reporter = JS_SetErrorReporter(cx, NULL); - bool punctureThrew = !UnwrapObjectChecked(cx, &caller); - JS_SetErrorReporter(cx, reporter); - if (punctureThrew) { - JS_ClearPendingException(cx); + if (caller.isWrapper() && !Wrapper::wrapperHandler(&caller)->isSafeToUnwrap()) { vp.setNull(); } else if (caller.isFunction()) { JSFunction *callerFun = caller.toFunction(); if (callerFun->isInterpreted() && callerFun->inStrictMode()) { JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL, JSMSG_CALLER_IS_STRICT); return false; }
--- a/js/src/jstypedarray.cpp +++ b/js/src/jstypedarray.cpp @@ -1868,19 +1868,21 @@ class TypedArrayTemplate * construct the new typed array in the compartment of the buffer, * so that the typed array can point directly at their buffer's * data without crossing compartment boundaries. So we use the * machinery underlying NonGenericMethodGuard directly to proxy the * native call. We will end up with a wrapper in the origin * compartment for a view in the target compartment referencing the * ArrayBuffer in that same compartment. */ - JSObject *wrapped = UnwrapObjectChecked(cx, bufobj); - if (!wrapped) + JSObject *wrapped = UnwrapObjectChecked(bufobj); + if (!wrapped) { + JS_ReportError(cx, "Permission denied to access object"); return NULL; + } if (wrapped->isArrayBuffer()) { /* * And for even more fun, the new view's prototype should be * set to the origin compartment's prototype object, not the * target's (specifically, the actual view in the target * compartment will use as its prototype a wrapper around the * origin compartment's view.prototype object). * @@ -3136,50 +3138,41 @@ JSFunctionSpec _typedArray::jsfuncs[] = JSObject *arrayBuffer_, uint32_t byteoffset, int32_t length) \ { \ MOZ_ASSERT(byteoffset <= INT32_MAX); \ Rooted<JSObject*> arrayBuffer(cx, arrayBuffer_); \ Rooted<JSObject*> proto(cx, NULL); \ return TypedArrayTemplate<NativeType>::fromBuffer(cx, arrayBuffer, byteoffset, length, \ 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(cx, obj))) { \ - cx->clearPendingException(); \ + if (!(obj = UnwrapObjectChecked(obj))) \ return false; \ - } \ Class *clasp = obj->getClass(); \ return (clasp == &TypedArray::classes[TypedArrayTemplate<NativeType>::ArrayTypeID()]); \ } IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Int8, int8_t) IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint8, uint8_t) IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint8Clamped, uint8_clamped) IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Int16, int16_t) IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint16, uint16_t) IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Int32, int32_t) IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint32, uint32_t) IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Float32, float) IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Float64, double) #define IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Name, ExternalType, InternalType) \ - JS_FRIEND_API(JSObject *) JS_GetObjectAs ## Name ## Array(JSContext *cx, \ - JSObject *obj, \ + JS_FRIEND_API(JSObject *) JS_GetObjectAs ## Name ## Array(JSObject *obj, \ uint32_t *length, \ ExternalType **data) \ { \ - if (obj->isWrapper()) { \ - MOZ_ASSERT(!cx->isExceptionPending()); \ - if (!(obj = UnwrapObjectChecked(cx, obj))) { \ - cx->clearPendingException(); \ - return NULL; \ - } \ - } \ + if (!(obj = UnwrapObjectChecked(obj))) \ + return NULL; \ \ Class *clasp = obj->getClass(); \ if (clasp != &TypedArray::classes[TypedArrayTemplate<InternalType>::ArrayTypeID()]) \ return NULL; \ \ *length = TypedArray::length(obj); \ *data = static_cast<ExternalType *>(TypedArray::viewData(obj)); \ \ @@ -3566,86 +3559,52 @@ js_InitTypedArrayClasses(JSContext *cx, return NULL; } return InitArrayBufferClass(cx); } /* JS Friend API */ -// The typed array friend API defines a number of accessor functions that want -// to unwrap an argument, but in certain rare cases may not have a cx available -// and so pass in NULL instead. Use UnwrapObjectChecked when possible. -static JSObject * -CheckedUnwrap(JSContext *cx, JSObject *obj) +JS_FRIEND_API(JSBool) +JS_IsArrayBufferObject(JSObject *obj) { - if (!cx) - return UnwrapObject(obj); - MOZ_ASSERT(!cx->isExceptionPending()); - obj = UnwrapObjectChecked(cx, obj); - MOZ_ASSERT(obj); - return obj; + obj = UnwrapObjectChecked(obj); + return obj ? obj->isArrayBuffer() : false; } JS_FRIEND_API(JSBool) -JS_IsArrayBufferObject(JSObject *objArg, JSContext *cx) +JS_IsTypedArrayObject(JSObject *obj) { - RootedObject obj_(cx, objArg); - MOZ_ASSERT(!cx->isExceptionPending()); - JSObject *obj = UnwrapObjectChecked(cx, obj_); - if (!obj) { - cx->clearPendingException(); - return false; - } - return obj->isArrayBuffer(); + obj = UnwrapObjectChecked(obj); + return obj ? obj->isTypedArray() : false; } JS_FRIEND_API(JSBool) -JS_IsTypedArrayObject(JSObject *objArg, JSContext *cx) +JS_IsArrayBufferViewObject(JSObject *obj) { - RootedObject obj_(cx, objArg); - MOZ_ASSERT(!cx->isExceptionPending()); - 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(); + obj = UnwrapObjectChecked(obj); + return obj ? (obj->isTypedArray() || obj->isDataView()) : false; } JS_FRIEND_API(uint32_t) -JS_GetArrayBufferByteLength(JSObject *obj, JSContext *maybecx) +JS_GetArrayBufferByteLength(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); - if (!obj) - return 0; - return obj->asArrayBuffer().byteLength(); + obj = UnwrapObjectChecked(obj); + return obj ? obj->asArrayBuffer().byteLength() : 0; } JS_FRIEND_API(uint8_t *) -JS_GetArrayBufferData(JSObject *obj, JSContext *maybecx) +JS_GetArrayBufferData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; ArrayBufferObject &buffer = obj->asArrayBuffer(); - if (!buffer.uninlineData(maybecx)) + if (!buffer.uninlineData(NULL)) return NULL; return buffer.dataPointer(); } JS_FRIEND_API(JSObject *) JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes) { JS_ASSERT(nbytes <= INT32_MAX); @@ -3675,271 +3634,258 @@ JS_AllocateArrayBufferContents(JSContext *data = reinterpret_cast<uint8_t*>(header->elements()); return true; } JS_PUBLIC_API(JSBool) JS_StealArrayBufferContents(JSContext *cx, JSObject *obj, void **contents, uint8_t **data) { - if (!(obj = UnwrapObjectChecked(cx, obj))) + if (!(obj = UnwrapObjectChecked(obj))) return false; if (!obj->isArrayBuffer()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS); return false; } if (!ArrayBufferObject::stealContents(cx, obj, contents, data)) return false; return true; } JS_FRIEND_API(uint32_t) -JS_GetTypedArrayLength(JSObject *obj, JSContext *maybecx) +JS_GetTypedArrayLength(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return 0; JS_ASSERT(obj->isTypedArray()); return TypedArray::length(obj); } JS_FRIEND_API(uint32_t) -JS_GetTypedArrayByteOffset(JSObject *obj, JSContext *maybecx) +JS_GetTypedArrayByteOffset(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return 0; JS_ASSERT(obj->isTypedArray()); return TypedArray::byteOffset(obj); } JS_FRIEND_API(uint32_t) -JS_GetTypedArrayByteLength(JSObject *obj, JSContext *maybecx) +JS_GetTypedArrayByteLength(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return 0; JS_ASSERT(obj->isTypedArray()); return TypedArray::byteLength(obj); } JS_FRIEND_API(JSArrayBufferViewType) -JS_GetTypedArrayType(JSObject *obj, JSContext *maybecx) +JS_GetTypedArrayType(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return ArrayBufferView::TYPE_MAX; JS_ASSERT(obj->isTypedArray()); return static_cast<JSArrayBufferViewType>(TypedArray::type(obj)); } JS_FRIEND_API(int8_t *) -JS_GetInt8ArrayData(JSObject *obj, JSContext *maybecx) +JS_GetInt8ArrayData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isTypedArray()); JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_INT8); return static_cast<int8_t *>(TypedArray::viewData(obj)); } JS_FRIEND_API(uint8_t *) -JS_GetUint8ArrayData(JSObject *obj, JSContext *maybecx) +JS_GetUint8ArrayData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isTypedArray()); JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_UINT8); return static_cast<uint8_t *>(TypedArray::viewData(obj)); } JS_FRIEND_API(uint8_t *) -JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *maybecx) +JS_GetUint8ClampedArrayData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isTypedArray()); JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_UINT8_CLAMPED); return static_cast<uint8_t *>(TypedArray::viewData(obj)); } JS_FRIEND_API(int16_t *) -JS_GetInt16ArrayData(JSObject *obj, JSContext *maybecx) +JS_GetInt16ArrayData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isTypedArray()); JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_INT16); return static_cast<int16_t *>(TypedArray::viewData(obj)); } JS_FRIEND_API(uint16_t *) -JS_GetUint16ArrayData(JSObject *obj, JSContext *maybecx) +JS_GetUint16ArrayData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isTypedArray()); JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_UINT16); return static_cast<uint16_t *>(TypedArray::viewData(obj)); } JS_FRIEND_API(int32_t *) -JS_GetInt32ArrayData(JSObject *obj, JSContext *maybecx) +JS_GetInt32ArrayData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isTypedArray()); JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_INT32); return static_cast<int32_t *>(TypedArray::viewData(obj)); } JS_FRIEND_API(uint32_t *) -JS_GetUint32ArrayData(JSObject *obj, JSContext *maybecx) +JS_GetUint32ArrayData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isTypedArray()); JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_UINT32); return static_cast<uint32_t *>(TypedArray::viewData(obj)); } JS_FRIEND_API(float *) -JS_GetFloat32ArrayData(JSObject *obj, JSContext *maybecx) +JS_GetFloat32ArrayData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isTypedArray()); JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_FLOAT32); return static_cast<float *>(TypedArray::viewData(obj)); } JS_FRIEND_API(double *) -JS_GetFloat64ArrayData(JSObject *obj, JSContext *maybecx) +JS_GetFloat64ArrayData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isTypedArray()); JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_FLOAT64); return static_cast<double *>(TypedArray::viewData(obj)); } JS_FRIEND_API(JSBool) -JS_IsDataViewObject(JSContext *cx, JSObject *objArg, JSBool *isDataView) +JS_IsDataViewObject(JSObject *obj) { - RootedObject obj_(cx, objArg); - JSObject *obj = CheckedUnwrap(cx, obj_); - if (!obj) - return false; - *isDataView = obj->isDataView(); - return true; + obj = UnwrapObjectChecked(obj); + return obj ? obj->isDataView() : false; } JS_FRIEND_API(uint32_t) -JS_GetDataViewByteOffset(JSObject *obj, JSContext *maybecx) +JS_GetDataViewByteOffset(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return 0; return obj->asDataView().byteOffset(); } JS_FRIEND_API(void *) -JS_GetDataViewData(JSObject *obj, JSContext *maybecx) +JS_GetDataViewData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isDataView()); return obj->asDataView().dataPointer(); } JS_FRIEND_API(uint32_t) -JS_GetDataViewByteLength(JSObject *obj, JSContext *maybecx) +JS_GetDataViewByteLength(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return 0; JS_ASSERT(obj->isDataView()); return obj->asDataView().byteLength(); } JS_FRIEND_API(void *) -JS_GetArrayBufferViewData(JSObject *obj, JSContext *maybecx) +JS_GetArrayBufferViewData(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isTypedArray() || obj->isDataView()); return obj->isDataView() ? obj->asDataView().dataPointer() : TypedArray::viewData(obj); } JS_FRIEND_API(JSObject *) -JS_GetArrayBufferViewBuffer(JSObject *obj, JSContext *maybecx) +JS_GetArrayBufferViewBuffer(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return NULL; JS_ASSERT(obj->isTypedArray() || obj->isDataView()); return &obj->getFixedSlot(BufferView::BUFFER_SLOT).toObject(); } JS_FRIEND_API(uint32_t) -JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *maybecx) +JS_GetArrayBufferViewByteLength(JSObject *obj) { - obj = CheckedUnwrap(maybecx, obj); + obj = UnwrapObjectChecked(obj); if (!obj) return 0; JS_ASSERT(obj->isTypedArray() || obj->isDataView()); return obj->isDataView() ? obj->asDataView().byteLength() : TypedArray::byteLengthValue(obj).toInt32(); } 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) { - if (obj->isWrapper()) { - if (!(obj = UnwrapObjectChecked(cx, obj))) { - cx->clearPendingException(); - return NULL; - } - } + if (!(obj = UnwrapObjectChecked(obj))) + return NULL; if (!(obj->isTypedArray() || obj->isDataView())) return NULL; *length = obj->isDataView() ? obj->asDataView().byteLength() : TypedArray::byteLengthValue(obj).toInt32(); *data = static_cast<uint8_t *>(obj->isDataView() ? obj->asDataView().dataPointer() : TypedArray::viewData(obj)); return obj; } 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(cx, obj))) { - cx->clearPendingException(); - return NULL; - } - } + if (!(obj = UnwrapObjectChecked(obj))) + return NULL; if (!obj->isArrayBuffer()) return NULL; *length = obj->asArrayBuffer().byteLength(); *data = obj->asArrayBuffer().dataPointer(); return obj; }
--- a/js/src/jswrapper.cpp +++ b/js/src/jswrapper.cpp @@ -104,43 +104,38 @@ js::UnwrapObject(JSObject *wrapped, bool wrapped = GetProxyPrivate(wrapped).toObjectOrNull(); } if (flagsp) *flagsp = flags; return wrapped; } JS_FRIEND_API(JSObject *) -js::UnwrapObjectChecked(JSContext *cx, RawObject objArg) +js::UnwrapObjectChecked(RawObject obj) { - RootedObject obj(cx, objArg); while (true) { JSObject *wrapper = obj; - obj = UnwrapOneChecked(cx, obj); + obj = UnwrapOneChecked(obj); if (!obj || obj == wrapper) return obj; } } JS_FRIEND_API(JSObject *) -js::UnwrapOneChecked(JSContext *cx, HandleObject obj) +js::UnwrapOneChecked(RawObject obj) { // Checked unwraps should never unwrap outer windows. if (!obj->isWrapper() || JS_UNLIKELY(!!obj->getClass()->ext.innerObject)) { return obj; } Wrapper *handler = Wrapper::wrapperHandler(obj); - if (!handler->isSafeToUnwrap()) { - JS_ReportError(cx, "Permission denied to access object"); - return NULL; - } - return Wrapper::wrappedObject(obj); + return handler->isSafeToUnwrap() ? Wrapper::wrappedObject(obj) : NULL; } bool js::IsCrossCompartmentWrapper(RawObject wrapper) { return wrapper->isWrapper() && !!(Wrapper::wrapperHandler(wrapper)->flags() & Wrapper::CROSS_COMPARTMENT); }
--- a/js/src/jswrapper.h +++ b/js/src/jswrapper.h @@ -250,22 +250,22 @@ IsWrapper(RawObject obj) JS_FRIEND_API(JSObject *) UnwrapObject(JSObject *obj, bool stopAtOuter = true, unsigned *flagsp = NULL); // Given a JSObject, returns that object stripped of wrappers. At each stage, // the security wrapper has the opportunity to veto the unwrap. Since checked // code should never be unwrapping outer window wrappers, we always stop at // outer windows. JS_FRIEND_API(JSObject *) -UnwrapObjectChecked(JSContext *cx, RawObject obj); +UnwrapObjectChecked(RawObject obj); // Unwrap only the outermost security wrapper, with the same semantics as // above. This is the checked version of Wrapper::wrappedObject. JS_FRIEND_API(JSObject *) -UnwrapOneChecked(JSContext *cx, HandleObject obj); +UnwrapOneChecked(RawObject obj); JS_FRIEND_API(bool) IsCrossCompartmentWrapper(RawObject obj); bool IsDeadProxyObject(RawObject obj); JSObject *
--- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -1814,19 +1814,21 @@ Debugger::unwrapDebuggeeArgument(JSConte if (obj->getClass() == &DebuggerObject_class) { Value rv = v; if (!unwrapDebuggeeValue(cx, &rv)) return NULL; obj = &rv.toObject(); } /* If we have a cross-compartment wrapper, dereference as far as is secure. */ - obj = UnwrapObjectChecked(cx, obj); - if (!obj) + obj = UnwrapObjectChecked(obj); + if (!obj) { + JS_ReportError(cx, "Permission denied to access object"); return NULL; + } /* If that produced an outer window, innerize it. */ obj = GetInnerObject(cx, obj); if (!obj) return NULL; /* If that didn't produce a global object, it's an error. */ if (!obj->isGlobal()) { @@ -4460,28 +4462,18 @@ DebuggerObject_evalInGlobalWithBindings( return DebuggerGenericEval(cx, "Debugger.Object.prototype.evalInGlobalWithBindings", args[0], &args[1], vp, dbg, referent, NULL); } static JSBool DebuggerObject_unwrap(JSContext *cx, unsigned argc, Value *vp) { THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "unwrap", args, dbg, referent); - JSObject *unwrapped = UnwrapOneChecked(cx, referent); + JSObject *unwrapped = UnwrapOneChecked(referent); 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(); return true; } *vp = ObjectValue(*unwrapped); if (!dbg->wrapDebuggeeValue(cx, vp)) return false; return true;
--- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -2706,17 +2706,17 @@ nsXPCComponents_Utils::LookupMethod(cons return NS_ERROR_XPC_BAD_CONVERT_JS; JSString *methodName = name.toString(); jsid methodId = INTERNED_STRING_TO_JSID(cx, JS_InternJSString(cx, methodName)); // If |obj| is a cross-compartment wrapper, try to puncture it. If this fails, // we don't have full access to the other compartment, in which case we throw. // Otherwise, enter the compartment. if (js::IsCrossCompartmentWrapper(obj)) { - obj = js::UnwrapOneChecked(cx, obj); + obj = js::UnwrapOneChecked(obj); if (!obj) return NS_ERROR_XPC_BAD_CONVERT_JS; } { // Enter the target compartment. JSAutoCompartment ac(cx, obj); @@ -3858,17 +3858,17 @@ nsXPCComponents_Utils::EvalInSandbox(con nsresult xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source, const char *filename, int32_t lineNo, JSVersion jsVersion, bool returnStringOnly, jsval *rval) { JS_AbortIfWrongThread(JS_GetRuntime(cx)); - sandbox = js::UnwrapObjectChecked(cx, sandbox); + sandbox = js::UnwrapObjectChecked(sandbox); if (!sandbox || js::GetObjectJSClass(sandbox) != &SandboxClass) { return NS_ERROR_INVALID_ARG; } nsIScriptObjectPrincipal *sop = (nsIScriptObjectPrincipal*)xpc_GetJSPrivate(sandbox); NS_ASSERTION(sop, "Invalid sandbox passed"); nsCOMPtr<nsIPrincipal> prin = sop->GetPrincipal();
--- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -1478,18 +1478,17 @@ failure: // Check that the tag part of the type matches the type // of the array. If the check succeeds, check that the size // of the output does not exceed UINT32_MAX bytes. Allocate // the memory and copy the elements by memcpy. static JSBool -CheckTargetAndPopulate(JSContext *cx, - const nsXPTType& type, +CheckTargetAndPopulate(const nsXPTType& type, uint8_t requiredType, size_t typeSize, uint32_t count, JSObject* tArr, void** output, nsresult* pErr) { // Check that the element type expected by the interface matches @@ -1510,113 +1509,112 @@ CheckTargetAndPopulate(JSContext *cx, size_t byteSize = count * typeSize; if (count > max || !(*output = nsMemory::Alloc(byteSize))) { if (pErr) *pErr = NS_ERROR_OUT_OF_MEMORY; return false; } - memcpy(*output, JS_GetArrayBufferViewData(tArr, cx), byteSize); + memcpy(*output, JS_GetArrayBufferViewData(tArr), byteSize); return true; } // Fast conversion of typed arrays to native using memcpy. // No float or double canonicalization is done. Called by // JSarray2Native whenever a TypedArray is met. ArrayBuffers // are not accepted; create a properly typed array view on them // first. The element type of array must match the XPCOM // type in size, type and signedness exactly. As an exception, // Uint8ClampedArray is allowed for arrays of uint8_t. // static JSBool -XPCConvert::JSTypedArray2Native(JSContext* cx, - void** d, +XPCConvert::JSTypedArray2Native(void** d, JSObject* jsArray, uint32_t count, const nsXPTType& type, nsresult* pErr) { NS_ABORT_IF_FALSE(jsArray, "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 // given size_is. - uint32_t len = JS_GetTypedArrayLength(jsArray, cx); + uint32_t len = JS_GetTypedArrayLength(jsArray); if (len < count) { if (pErr) *pErr = NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY; return false; } void* output = nullptr; - switch (JS_GetTypedArrayType(jsArray, cx)) { + switch (JS_GetTypedArrayType(jsArray)) { case js::ArrayBufferView::TYPE_INT8: - if (!CheckTargetAndPopulate(cx, nsXPTType::T_I8, type, + if (!CheckTargetAndPopulate(nsXPTType::T_I8, type, sizeof(int8_t), count, jsArray, &output, pErr)) { return false; } break; case js::ArrayBufferView::TYPE_UINT8: case js::ArrayBufferView::TYPE_UINT8_CLAMPED: - if (!CheckTargetAndPopulate(cx, nsXPTType::T_U8, type, + if (!CheckTargetAndPopulate(nsXPTType::T_U8, type, sizeof(uint8_t), count, jsArray, &output, pErr)) { return false; } break; case js::ArrayBufferView::TYPE_INT16: - if (!CheckTargetAndPopulate(cx, nsXPTType::T_I16, type, + if (!CheckTargetAndPopulate(nsXPTType::T_I16, type, sizeof(int16_t), count, jsArray, &output, pErr)) { return false; } break; case js::ArrayBufferView::TYPE_UINT16: - if (!CheckTargetAndPopulate(cx, nsXPTType::T_U16, type, + if (!CheckTargetAndPopulate(nsXPTType::T_U16, type, sizeof(uint16_t), count, jsArray, &output, pErr)) { return false; } break; case js::ArrayBufferView::TYPE_INT32: - if (!CheckTargetAndPopulate(cx, nsXPTType::T_I32, type, + if (!CheckTargetAndPopulate(nsXPTType::T_I32, type, sizeof(int32_t), count, jsArray, &output, pErr)) { return false; } break; case js::ArrayBufferView::TYPE_UINT32: - if (!CheckTargetAndPopulate(cx, nsXPTType::T_U32, type, + if (!CheckTargetAndPopulate(nsXPTType::T_U32, type, sizeof(uint32_t), count, jsArray, &output, pErr)) { return false; } break; case js::ArrayBufferView::TYPE_FLOAT32: - if (!CheckTargetAndPopulate(cx, nsXPTType::T_FLOAT, type, + if (!CheckTargetAndPopulate(nsXPTType::T_FLOAT, type, sizeof(float), count, jsArray, &output, pErr)) { return false; } break; case js::ArrayBufferView::TYPE_FLOAT64: - if (!CheckTargetAndPopulate(cx, nsXPTType::T_DOUBLE, type, + if (!CheckTargetAndPopulate(nsXPTType::T_DOUBLE, type, sizeof(double), count, jsArray, &output, pErr)) { return false; } break; // Yet another array type was defined? It is not supported yet... default: @@ -1660,18 +1658,18 @@ XPCConvert::JSArray2Native(JSContext* cx if (pErr) *pErr = NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY; return false; } JSObject* jsarray = &s.toObject(); // If this is a typed array, then try a fast conversion with memcpy. - if (JS_IsTypedArrayObject(jsarray, cx)) { - return JSTypedArray2Native(cx, d, jsarray, count, type, pErr); + if (JS_IsTypedArrayObject(jsarray)) { + return JSTypedArray2Native(d, jsarray, count, type, pErr); } if (!JS_IsArrayObject(cx, jsarray)) { if (pErr) *pErr = NS_ERROR_XPC_CANT_CONVERT_OBJECT_TO_ARRAY; return false; }
--- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -3363,18 +3363,17 @@ public: jsval* d, const void** s, const nsXPTType& type, const nsID* iid, uint32_t count, nsresult* pErr); static JSBool JSArray2Native(JSContext* cx, void** d, jsval s, uint32_t count, const nsXPTType& type, const nsID* iid, nsresult* pErr); - static JSBool JSTypedArray2Native(JSContext* cx, - void** d, + static JSBool JSTypedArray2Native(void** d, JSObject* jsarray, uint32_t count, const nsXPTType& type, nsresult* pErr); static JSBool NativeStringWithSize2JS(JSContext* cx, jsval* d, const void* s, const nsXPTType& type,
--- a/js/xpconnect/wrappers/AccessCheck.cpp +++ b/js/xpconnect/wrappers/AccessCheck.cpp @@ -349,17 +349,17 @@ ExposedPropertiesOnly::check(JSContext * JSAutoCompartment ac(cx, wrappedObject); JSBool found = false; if (!JS_HasPropertyById(cx, wrappedObject, exposedPropsId, &found)) return false; // Always permit access to "length" and indexed properties of arrays. if ((JS_IsArrayObject(cx, wrappedObject) || - JS_IsTypedArrayObject(wrappedObject, cx)) && + JS_IsTypedArrayObject(wrappedObject)) && ((JSID_IS_INT(id) && JSID_TO_INT(id) >= 0) || (JSID_IS_STRING(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "length")))) { return true; // Allow } // If no __exposedProps__ existed, deny access. if (!found) { // Everything below here needs to be done in the wrapper's compartment.