зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1289080: Don't allow call_indirect without a table and memory accesses without memory; r=luke
MozReview-Commit-ID: DkuyBiGsaxs --HG-- extra : rebase_source : d051b7e8c9e7c32ba60a6e37bb4c6dc98dc36ef9
This commit is contained in:
Родитель
185149d31c
Коммит
feab551c2f
|
@ -79,6 +79,12 @@ class FunctionDecoder
|
|||
return iter().notYetImplemented("i64 NYI on this platform");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkHasMemory() {
|
||||
if (!mg().usesMemory())
|
||||
return iter().fail("can't touch memory without memory");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
@ -146,6 +152,9 @@ DecodeCall(FunctionDecoder& f)
|
|||
static bool
|
||||
DecodeCallIndirect(FunctionDecoder& f)
|
||||
{
|
||||
if (!f.mg().numTables())
|
||||
return f.iter().fail("can't call_indirect without a table");
|
||||
|
||||
uint32_t sigIndex;
|
||||
uint32_t arity;
|
||||
if (!f.iter().readCallIndirect(&sigIndex, &arity))
|
||||
|
@ -398,53 +407,71 @@ DecodeExpr(FunctionDecoder& f)
|
|||
return f.iter().readConversion(ValType::F32, ValType::F64, nullptr);
|
||||
case Expr::I32Load8S:
|
||||
case Expr::I32Load8U:
|
||||
return f.iter().readLoad(ValType::I32, 1, nullptr);
|
||||
return f.checkHasMemory() &&
|
||||
f.iter().readLoad(ValType::I32, 1, nullptr);
|
||||
case Expr::I32Load16S:
|
||||
case Expr::I32Load16U:
|
||||
return f.iter().readLoad(ValType::I32, 2, nullptr);
|
||||
return f.checkHasMemory() &&
|
||||
f.iter().readLoad(ValType::I32, 2, nullptr);
|
||||
case Expr::I32Load:
|
||||
return f.iter().readLoad(ValType::I32, 4, nullptr);
|
||||
return f.checkHasMemory() &&
|
||||
f.iter().readLoad(ValType::I32, 4, nullptr);
|
||||
case Expr::I64Load8S:
|
||||
case Expr::I64Load8U:
|
||||
return f.checkI64Support() &&
|
||||
f.checkHasMemory() &&
|
||||
f.iter().readLoad(ValType::I64, 1, nullptr);
|
||||
case Expr::I64Load16S:
|
||||
case Expr::I64Load16U:
|
||||
return f.checkI64Support() &&
|
||||
f.checkHasMemory() &&
|
||||
f.iter().readLoad(ValType::I64, 2, nullptr);
|
||||
case Expr::I64Load32S:
|
||||
case Expr::I64Load32U:
|
||||
return f.checkI64Support() &&
|
||||
f.checkHasMemory() &&
|
||||
f.iter().readLoad(ValType::I64, 4, nullptr);
|
||||
case Expr::I64Load:
|
||||
return f.checkI64Support() &&
|
||||
f.checkHasMemory() &&
|
||||
f.iter().readLoad(ValType::I64, 8, nullptr);
|
||||
case Expr::F32Load:
|
||||
return f.iter().readLoad(ValType::F32, 4, nullptr);
|
||||
return f.checkHasMemory() &&
|
||||
f.iter().readLoad(ValType::F32, 4, nullptr);
|
||||
case Expr::F64Load:
|
||||
return f.iter().readLoad(ValType::F64, 8, nullptr);
|
||||
return f.checkHasMemory() &&
|
||||
f.iter().readLoad(ValType::F64, 8, nullptr);
|
||||
case Expr::I32Store8:
|
||||
return f.iter().readStore(ValType::I32, 1, nullptr, nullptr);
|
||||
return f.checkHasMemory() &&
|
||||
f.iter().readStore(ValType::I32, 1, nullptr, nullptr);
|
||||
case Expr::I32Store16:
|
||||
return f.iter().readStore(ValType::I32, 2, nullptr, nullptr);
|
||||
return f.checkHasMemory() &&
|
||||
f.iter().readStore(ValType::I32, 2, nullptr, nullptr);
|
||||
case Expr::I32Store:
|
||||
return f.iter().readStore(ValType::I32, 4, nullptr, nullptr);
|
||||
return f.checkHasMemory() &&
|
||||
f.iter().readStore(ValType::I32, 4, nullptr, nullptr);
|
||||
case Expr::I64Store8:
|
||||
return f.checkI64Support() &&
|
||||
f.checkHasMemory() &&
|
||||
f.iter().readStore(ValType::I64, 1, nullptr, nullptr);
|
||||
case Expr::I64Store16:
|
||||
return f.checkI64Support() &&
|
||||
f.checkHasMemory() &&
|
||||
f.iter().readStore(ValType::I64, 2, nullptr, nullptr);
|
||||
case Expr::I64Store32:
|
||||
return f.checkI64Support() &&
|
||||
f.checkHasMemory() &&
|
||||
f.iter().readStore(ValType::I64, 4, nullptr, nullptr);
|
||||
case Expr::I64Store:
|
||||
return f.checkI64Support() &&
|
||||
f.checkHasMemory() &&
|
||||
f.iter().readStore(ValType::I64, 8, nullptr, nullptr);
|
||||
case Expr::F32Store:
|
||||
return f.iter().readStore(ValType::F32, 4, nullptr, nullptr);
|
||||
return f.checkHasMemory() &&
|
||||
f.iter().readStore(ValType::F32, 4, nullptr, nullptr);
|
||||
case Expr::F64Store:
|
||||
return f.iter().readStore(ValType::F64, 8, nullptr, nullptr);
|
||||
return f.checkHasMemory() &&
|
||||
f.iter().readStore(ValType::F64, 8, nullptr, nullptr);
|
||||
case Expr::Br:
|
||||
return f.iter().readBr(nullptr, nullptr, nullptr);
|
||||
case Expr::BrIf:
|
||||
|
|
|
@ -153,6 +153,7 @@ class MOZ_STACK_CLASS ModuleGenerator
|
|||
uint32_t minMemoryLength() const { return shared_->minMemoryLength; }
|
||||
|
||||
// Tables:
|
||||
uint32_t numTables() const { return numTables_; }
|
||||
const TableDescVector& tables() const { return shared_->tables; }
|
||||
|
||||
// Signatures:
|
||||
|
|
|
@ -104,6 +104,52 @@ function testStoreOOB(type, ext, base, offset, align, value) {
|
|||
assertErrorMessage(() => storeModule(type, ext, offset, align).store(base, value), Error, /invalid or out-of-range index/);
|
||||
}
|
||||
|
||||
function badLoadModule(type, ext) {
|
||||
return wasmEvalText( `(module (func (param i32) (${type}.load${ext} (get_local 0))) (export "" 0))`);
|
||||
}
|
||||
|
||||
function badStoreModule(type, ext) {
|
||||
return wasmEvalText( `(module (func (param i32) (${type}.store${ext} (get_local 0) (${type}.const 0))) (export "" 0))`);
|
||||
}
|
||||
|
||||
// Can't touch memory.
|
||||
for (let [type, ext] of [
|
||||
['i32', ''],
|
||||
['i32', '8_s'],
|
||||
['i32', '8_u'],
|
||||
['i32', '16_s'],
|
||||
['i32', '16_u'],
|
||||
['i64', ''],
|
||||
['i64', '8_s'],
|
||||
['i64', '8_u'],
|
||||
['i64', '16_s'],
|
||||
['i64', '16_u'],
|
||||
['i64', '32_s'],
|
||||
['i64', '32_u'],
|
||||
['f32', ''],
|
||||
['f64', ''],
|
||||
])
|
||||
{
|
||||
if (type !== 'i64' || hasI64())
|
||||
assertErrorMessage(() => badLoadModule(type, ext), TypeError, /can't touch memory/);
|
||||
}
|
||||
|
||||
for (let [type, ext] of [
|
||||
['i32', ''],
|
||||
['i32', '8'],
|
||||
['i32', '16'],
|
||||
['i64', ''],
|
||||
['i64', '8'],
|
||||
['i64', '16'],
|
||||
['i64', '32'],
|
||||
['f32', ''],
|
||||
['f64', ''],
|
||||
])
|
||||
{
|
||||
if (type !== 'i64' || hasI64())
|
||||
assertErrorMessage(() => badStoreModule(type, ext), TypeError, /can't touch memory/);
|
||||
}
|
||||
|
||||
// Test bounds checks and edge cases.
|
||||
const align = 0;
|
||||
|
||||
|
|
|
@ -403,6 +403,8 @@ if (hasI64()) {
|
|||
assertErrorMessage(() => wasmEvalText('(module (import "a" "" (result i64)))'), TypeError, /NYI/);
|
||||
}
|
||||
|
||||
assertErrorMessage(() => wasmEvalText(`(module (type $t (func)) (func (call_indirect $t (i32.const 0))))`), TypeError, /can't call_indirect without a table/);
|
||||
|
||||
var {v2i, i2i, i2v} = wasmEvalText(`(module
|
||||
(type (func (result i32)))
|
||||
(type (func (param i32) (result i32)))
|
||||
|
|
Загрузка…
Ссылка в новой задаче