-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Validate local count in local.set/get/tee #363
Conversation
lib/fizzy/parser.cpp
Outdated
uint64_t local_count = 0; | ||
for (const auto& l : locals_vec) | ||
{ | ||
local_count += l.count; | ||
if (local_count > std::numeric_limits<uint32_t>::max()) | ||
throw parser_error{"too many local variables"}; | ||
} | ||
|
||
auto [code, pos2] = parse_expr(pos1, end, static_cast<uint32_t>(local_count), func_idx, module); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First I tried to pass on locals_vec
but realised it would need to do this counting again. We can refactor this when type checking is introduced, because then we'll need the types of locals.
lib/fizzy/parser_expr.cpp
Outdated
@@ -564,6 +566,13 @@ parser_result<Code> parse_expr( | |||
{ | |||
uint32_t imm; | |||
std::tie(imm, pos) = leb128u_decode<uint32_t>(pos, end); | |||
|
|||
if (instr == Instr::local_get || instr == Instr::local_set) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to add local_tee
here. However it seems that doesn't change the number of successful validation tests, which suggests they are not covered upstream.
2320ef5
to
4d72375
Compare
Codecov Report
@@ Coverage Diff @@
## master #363 +/- ##
========================================
Coverage 99.32% 99.32%
========================================
Files 42 42
Lines 12692 12829 +137
========================================
+ Hits 12606 12743 +137
Misses 86 86 |
327178a
to
62a933e
Compare
lib/fizzy/parser_expr.cpp
Outdated
@@ -148,6 +150,12 @@ parser_result<Code> parse_expr( | |||
// The function's implicit block. | |||
control_stack.emplace(Instr::block, function_arity, 0); | |||
|
|||
// This is needed for aiding validation. | |||
assert((uint64_t{local_count} + module.typesec[func_type_idx].inputs.size()) <= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should make this a proper parser error... or is this more like a missing case in the spec?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also validation tests are missing.
d04fa37
to
cc6693e
Compare
const uint8_t* input, const uint8_t* end, FuncIdx func_idx, const Module& module); | ||
/// @param input The beginning of the expr binary input. | ||
/// @param end The end of the binary input. | ||
/// @param local_count The number of locals defined. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are going to need types for type validation, maybe makes sense to pass const Locals&
right away?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was discussed in the an earlier comment. I started out with std::vector<Locals>
but then local counting and validation of it has to be moved into parse_expr
, which I think isn't the nicest.
I'd defer this work once we implement type checking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe create Code
object in Module
before parse_expr
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe create
Code
object inModule
beforeparse_expr
?
I would advice against this, because it would make code
confusingly both input and output parameter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not mean that parse_expr
should return Code
. Maybe it should return Expr
. But is also bad to ask parse_expr
to move the information about locals (here local_count
, maybe type information later) from one place to another. That's unneeded and trivial responsibility.
lib/fizzy/parser_expr.cpp
Outdated
// This is needed for aiding validation. | ||
assert((uint64_t{local_count} + module.typesec[func_type_idx].inputs.size()) <= | ||
std::numeric_limits<uint32_t>::max()); | ||
const uint32_t max_local_index = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it's not max index, maybe total_local_arg_count
or local_and_arg_count
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't it max index? The immediate it is compared against is called "local index".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it's max index + 1
b79d3dd
to
0488136
Compare
Looks ok, needs a test fro validation failure. |
7ae75ca
to
ddf45be
Compare
@gumb0 added tests. |
// The function's implicit block. | ||
control_stack.emplace(Instr::block, function_arity, 0); | ||
|
||
// This is needed for aiding validation. | ||
assert( | ||
(uint64_t{local_count} + func_type.inputs.size()) <= std::numeric_limits<uint32_t>::max()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this case is also missing from the spectests.
99a24b8
to
2813c84
Compare
No description provided.