Changeset 209874 in webkit
- Timestamp:
- Dec 15, 2016 2:08:38 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r209866 r209874 1 2016-12-15 JF Bastien <jfbastien@apple.com> 2 3 WebAssembly API: improve data section errors 4 https://bugs.webkit.org/show_bug.cgi?id=165733 5 6 Reviewed by Keith Miller. 7 8 * wasm/js-api/element-data.js: Added. 9 (ElementBeforeData.set const): 10 (ElementBeforeData): check the order of initialization, which is observable on failure 11 * wasm/js-api/test_Data.js: 12 (DataSectionWithoutMemory): 13 (DataSectionOffTheEnd): Deleted. 14 (DataSectionPartlyOffTheEnd): Deleted. 15 (DataSectionEmptyOffTheEnd): Deleted. 16 (DataSectionSeenByStart): Deleted. 17 1 18 2016-12-15 Keith Miller <keith_miller@apple.com> 2 19 -
trunk/JSTests/wasm/js-api/test_Data.js
r209651 r209874 5 5 const pageSizeInBytes = 64 * 1024; 6 6 const memoryDescription = { initial: memSizeInPages, maximum: memSizeInPages }; 7 const emptyMemory = { initial: 0, maximum: 2 }; 7 8 8 9 // FIXME Some corner cases are ill-specified: https://github.com/WebAssembly/design/issues/897 10 11 const assertMemoryAllZero = memory => { 12 const buffer = new Uint8Array(memory.buffer); 13 for (let idx = 0; idx < buffer.length; ++idx) { 14 const value = buffer[idx]; 15 assert.eq(value, 0x00); 16 } 17 }; 9 18 10 19 (function DataSection() { … … 37 46 })(); 38 47 48 (function DataSectionWithoutMemory() { 49 const builder = (new Builder()) 50 .Type().End() 51 .Data() 52 .Segment([0xff]).Offset(0).End() 53 .End(); 54 const bin = builder.WebAssembly().get(); 55 assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, `couldn't parse section Data: Data segments (evaluating 'new WebAssembly.Module(bin)')`); 56 })(); 57 58 (function EmptyDataSectionWithoutMemory() { 59 const builder = (new Builder()) 60 .Type().End() 61 .Data() 62 .Segment([]).Offset(0).End() 63 .End(); 64 const bin = builder.WebAssembly().get(); 65 assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, `couldn't parse section Data: Data segments (evaluating 'new WebAssembly.Module(bin)')`); 66 })(); 67 68 (function DataSectionBiggerThanMemory() { 69 const builder = (new Builder()) 70 .Type().End() 71 .Import().Memory("imp", "memory", memoryDescription).End() 72 .Data() 73 .Segment(Array(memSizeInPages * pageSizeInBytes + 1).fill(0xff)).Offset(0).End() 74 .End(); 75 const bin = builder.WebAssembly().get(); 76 const module = new WebAssembly.Module(bin); 77 const memory = new WebAssembly.Memory(memoryDescription); 78 assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), RangeError, `Invalid data segment initialization: segment of 65537 bytes memory of 65536 bytes, at offset 0, segment is too big`); 79 assertMemoryAllZero(memory); 80 })(); 81 39 82 (function DataSectionOffTheEnd() { 40 83 const builder = (new Builder()) … … 47 90 const module = new WebAssembly.Module(bin); 48 91 const memory = new WebAssembly.Memory(memoryDescription); 49 assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), RangeError, `Data segment initializes memory out of range`); 50 const buffer = new Uint8Array(memory.buffer); 51 for (let idx = 0; idx < memSizeInPages * pageSizeInBytes; ++idx) { 52 const value = buffer[idx]; 53 assert.eq(value, 0x00); 54 } 92 assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), RangeError, `Invalid data segment initialization: segment of 1 bytes memory of 65536 bytes, at offset 65536, segment writes outside of memory`); 93 assertMemoryAllZero(memory); 55 94 })(); 56 95 … … 65 104 const module = new WebAssembly.Module(bin); 66 105 const memory = new WebAssembly.Memory(memoryDescription); 67 assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), RangeError, `Data segment initializes memory out of range`); 68 const buffer = new Uint8Array(memory.buffer); 69 for (let idx = 0; idx < memSizeInPages * pageSizeInBytes; ++idx) { 70 const value = buffer[idx]; 71 assert.eq(value, 0x00); 72 } 106 assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), RangeError, `Invalid data segment initialization: segment of 2 bytes memory of 65536 bytes, at offset 65535, segment writes outside of memory`); 107 assertMemoryAllZero(memory); 73 108 })(); 74 109 … … 84 119 const memory = new WebAssembly.Memory(memoryDescription); 85 120 const instance = new WebAssembly.Instance(module, { imp: { memory: memory } }); 86 const buffer = new Uint8Array(memory.buffer); 87 for (let idx = 0; idx < memSizeInPages * pageSizeInBytes; ++idx) { 88 const value = buffer[idx]; 89 assert.eq(value, 0x00); 90 } 121 assertMemoryAllZero(memory); 122 })(); 123 124 (function DataSectionEmptyOffTheEndWithEmptyMemory() { 125 const builder = (new Builder()) 126 .Type().End() 127 .Import().Memory("imp", "memory", emptyMemory).End() 128 .Data() 129 .Segment([]).Offset(memSizeInPages * pageSizeInBytes).End() 130 .End(); 131 const bin = builder.WebAssembly().get(); 132 const module = new WebAssembly.Module(bin); 133 const memory = new WebAssembly.Memory(emptyMemory); 134 const instance = new WebAssembly.Instance(module, { imp: { memory: memory } }); 135 assertMemoryAllZero(memory); 91 136 })(); 92 137 -
trunk/Source/JavaScriptCore/ChangeLog
r209872 r209874 1 2016-12-15 JF Bastien <jfbastien@apple.com> 2 3 WebAssembly API: improve data section errors, initialize after Element 4 https://bugs.webkit.org/show_bug.cgi?id=165733 5 6 Reviewed by Keith Miller. 7 8 * wasm/WasmModuleParser.cpp: 9 (JSC::Wasm::ModuleParser::parseData): Data section without Memory section or import is a validation error 10 * wasm/js/WebAssemblyModuleRecord.cpp: 11 (JSC::dataSegmentFail): 12 (JSC::WebAssemblyModuleRecord::evaluate): tighten checks (though the spec isn't fully baked), and move after Element initialization 13 1 14 2016-12-15 Keith Miller <keith_miller@apple.com> 2 15 -
trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp
r209850 r209874 725 725 { 726 726 uint32_t segmentCount; 727 if (!m_module->memory) 728 return false; 727 729 if (!parseVarUInt32(segmentCount) 728 730 || segmentCount == std::numeric_limits<uint32_t>::max() -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
r209850 r209874 195 195 } 196 196 197 template <typename Scope, typename N, typename ...Args> 198 NEVER_INLINE static JSValue dataSegmentFail(ExecState* state, Scope& scope, N memorySize, N segmentSize, N offset, Args... args) 199 { 200 return throwException(state, scope, createRangeError(state, makeString(ASCIILiteral("Invalid data segment initialization: segment of "), String::number(segmentSize), ASCIILiteral(" bytes memory of "), String::number(memorySize), ASCIILiteral(" bytes, at offset "), String::number(offset), args...))); 201 } 202 197 203 JSValue WebAssemblyModuleRecord::evaluate(ExecState* state) 198 204 { 199 205 VM& vm = state->vm(); 200 206 auto scope = DECLARE_THROW_SCOPE(vm); 201 202 if (JSWebAssemblyMemory* jsMemory = m_instance->memory()) {203 uint8_t* memory = reinterpret_cast<uint8_t*>(jsMemory->memory()->memory());204 auto sizeInBytes = jsMemory->memory()->size();205 if (memory) {206 const Vector<Wasm::Segment::Ptr>& data = m_instance->module()->moduleInformation().data;207 for (auto& segment : data) {208 if (segment->sizeInBytes) {209 if (sizeInBytes < segment->sizeInBytes210 || segment->offset > sizeInBytes211 || segment->offset > sizeInBytes - segment->sizeInBytes)212 return throwException(state, scope, createRangeError(state, ASCIILiteral("Data segment initializes memory out of range")));213 memcpy(memory + segment->offset, &segment->byte(0), segment->sizeInBytes);214 }215 }216 }217 }218 207 219 208 { … … 262 251 } 263 252 253 { 254 const Vector<Wasm::Segment::Ptr>& data = m_instance->module()->moduleInformation().data; 255 JSWebAssemblyMemory* jsMemory = m_instance->memory(); 256 if (!data.isEmpty()) { 257 RELEASE_ASSERT(jsMemory); // It is a validation error for a Data section to exist without a Memory section or import. 258 uint8_t* memory = reinterpret_cast<uint8_t*>(jsMemory->memory()->memory()); 259 RELEASE_ASSERT(memory); 260 auto sizeInBytes = jsMemory->memory()->size(); 261 for (auto& segment : data) { 262 if (segment->sizeInBytes) { 263 if (UNLIKELY(sizeInBytes < segment->sizeInBytes)) 264 return dataSegmentFail(state, scope, sizeInBytes, segment->sizeInBytes, segment->offset, ASCIILiteral(", segment is too big")); 265 if (UNLIKELY(segment->offset > sizeInBytes - segment->sizeInBytes)) 266 return dataSegmentFail(state, scope, sizeInBytes, segment->sizeInBytes, segment->offset, ASCIILiteral(", segment writes outside of memory")); 267 memcpy(memory + segment->offset, &segment->byte(0), segment->sizeInBytes); 268 } 269 } 270 } 271 } 272 264 273 if (WebAssemblyFunction* startFunction = m_startFunction.get()) { 265 274 ProtoCallFrame protoCallFrame; … … 268 277 RETURN_IF_EXCEPTION(scope, { }); 269 278 } 279 270 280 return jsUndefined(); 271 281 }
Note: See TracChangeset
for help on using the changeset viewer.