Skip to content

Commit f46d3d9

Browse files
committed
Throw the right type of Error when constructing a WebAssembly.Memory
1 parent 303f24f commit f46d3d9

File tree

2 files changed

+31
-21
lines changed

2 files changed

+31
-21
lines changed

lib/Runtime/Library/WebAssemblyMemory.cpp

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,33 @@ WebAssemblyMemory::WebAssemblyMemory(ArrayBufferBase* buffer, uint32 initial, ui
2222
}
2323

2424

25-
_Must_inspect_result_ bool WebAssemblyMemory::AreLimitsValid(uint32 initial, uint32 maximum)
25+
void WebAssemblyMemory::CheckLimits(ScriptContext * scriptContext, uint32 initial, uint32 maximum)
2626
{
27-
return initial <= maximum && initial <= Wasm::Limits::GetMaxMemoryInitialPages() && maximum <= Wasm::Limits::GetMaxMemoryMaximumPages();
27+
if (maximum < initial)
28+
{
29+
JavascriptError::ThrowRangeError(scriptContext, JSERR_ArgumentOutOfRange);
30+
}
31+
if (initial > Wasm::Limits::GetMaxMemoryInitialPages())
32+
{
33+
JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_Invalid, _u("descriptor.initial"));
34+
}
35+
if (maximum > Wasm::Limits::GetMaxMemoryMaximumPages())
36+
{
37+
JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_Invalid, _u("descriptor.maximum"));
38+
}
2839
}
2940

3041

31-
_Must_inspect_result_ bool WebAssemblyMemory::AreLimitsValid(uint32 initial, uint32 maximum, uint32 bufferLength)
42+
void WebAssemblyMemory::CheckLimits(ScriptContext * scriptContext, uint32 initial, uint32 maximum, uint32 bufferLength)
3243
{
33-
if (!AreLimitsValid(initial, maximum))
34-
{
35-
return false;
36-
}
44+
CheckLimits(scriptContext, initial, maximum);
3745
// Do the mul after initial checks to avoid potential unneeded OOM exception
3846
const uint32 initBytes = UInt32Math::Mul<WebAssembly::PageSize>(initial);
3947
const uint32 maxBytes = UInt32Math::Mul<WebAssembly::PageSize>(maximum);
40-
return initBytes <= bufferLength && bufferLength <= maxBytes;
48+
if (initBytes > bufferLength || bufferLength > maxBytes)
49+
{
50+
JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_Invalid);
51+
}
4152
}
4253

4354
Var
@@ -60,10 +71,14 @@ WebAssemblyMemory::NewInstance(RecyclableObject* function, CallInfo callInfo, ..
6071

6172
if (args.Info.Count < 2 || !JavascriptOperators::IsObject(args[1]))
6273
{
63-
JavascriptError::ThrowTypeError(scriptContext, JSERR_NeedObject, _u("memoryDescriptor"));
74+
JavascriptError::ThrowTypeError(scriptContext, JSERR_NeedObject, _u("descriptor"));
6475
}
6576
DynamicObject * memoryDescriptor = VarTo<DynamicObject>(args[1]);
6677

78+
if (!JavascriptOperators::OP_HasProperty(memoryDescriptor, PropertyIds::initial, scriptContext))
79+
{
80+
JavascriptError::ThrowTypeError(scriptContext, JSERR_NeedNumber, _u("descriptor.initial"));
81+
}
6782
Var initVar = JavascriptOperators::OP_GetProperty(memoryDescriptor, PropertyIds::initial, scriptContext);
6883
uint32 initial = WebAssembly::ToNonWrappingUint32(initVar, scriptContext);
6984

@@ -271,10 +286,7 @@ WebAssemblyMemory::EntryGetterBuffer(RecyclableObject* function, CallInfo callIn
271286
WebAssemblyMemory *
272287
WebAssemblyMemory::CreateMemoryObject(uint32 initial, uint32 maximum, bool isShared, ScriptContext * scriptContext)
273288
{
274-
if (!AreLimitsValid(initial, maximum))
275-
{
276-
JavascriptError::ThrowRangeError(scriptContext, JSERR_ArgumentOutOfRange);
277-
}
289+
CheckLimits(scriptContext, initial, maximum);
278290
uint32 byteLength = UInt32Math::Mul<WebAssembly::PageSize>(initial);
279291
ArrayBufferBase* buffer = nullptr;
280292
#ifdef ENABLE_WASM_THREADS
@@ -300,10 +312,7 @@ WebAssemblyMemory::CreateMemoryObject(uint32 initial, uint32 maximum, bool isSha
300312

301313
WebAssemblyMemory * WebAssemblyMemory::CreateForExistingBuffer(uint32 initial, uint32 maximum, uint32 currentByteLength, ScriptContext * scriptContext)
302314
{
303-
if (!AreLimitsValid(initial, maximum, currentByteLength))
304-
{
305-
JavascriptError::ThrowRangeError(scriptContext, JSERR_ArgumentOutOfRange);
306-
}
315+
CheckLimits(scriptContext, initial, maximum, currentByteLength);
307316
ArrayBufferBase* buffer = scriptContext->GetLibrary()->CreateWebAssemblyArrayBuffer(currentByteLength);
308317
Assert(buffer);
309318
if (currentByteLength > 0 && buffer->GetByteLength() == 0)
@@ -317,10 +326,11 @@ WebAssemblyMemory * WebAssemblyMemory::CreateForExistingBuffer(uint32 initial, u
317326
#ifdef ENABLE_WASM_THREADS
318327
WebAssemblyMemory * WebAssemblyMemory::CreateFromSharedContents(uint32 initial, uint32 maximum, SharedContents* sharedContents, ScriptContext * scriptContext)
319328
{
320-
if (!sharedContents || !AreLimitsValid(initial, maximum, sharedContents->bufferLength))
329+
if (!sharedContents)
321330
{
322-
JavascriptError::ThrowRangeError(scriptContext, JSERR_ArgumentOutOfRange);
331+
JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_Invalid);
323332
}
333+
CheckLimits(scriptContext, initial, maximum, sharedContents->bufferLength);
324334
ArrayBufferBase* buffer = scriptContext->GetLibrary()->CreateWebAssemblySharedArrayBuffer(sharedContents);
325335
return RecyclerNewFinalized(scriptContext->GetRecycler(), WebAssemblyMemory, buffer, initial, maximum, scriptContext->GetLibrary()->GetWebAssemblyMemoryType());
326336
}

lib/Runtime/Library/WebAssemblyMemory.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ namespace Js
5050
#endif
5151
private:
5252
WebAssemblyMemory(ArrayBufferBase* buffer, uint32 initial, uint32 maximum, DynamicType * type);
53-
static _Must_inspect_result_ bool AreLimitsValid(uint32 initial, uint32 maximum);
54-
static _Must_inspect_result_ bool AreLimitsValid(uint32 initial, uint32 maximum, uint32 bufferLength);
53+
static void CheckLimits(ScriptContext * scriptContext, uint32 initial, uint32 maximum);
54+
static void CheckLimits(ScriptContext * scriptContext, uint32 initial, uint32 maximum, uint32 bufferLength);
5555

5656
Field(ArrayBufferBase*) m_buffer;
5757

0 commit comments

Comments
 (0)