-
Notifications
You must be signed in to change notification settings - Fork 43
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
Fix comparison of RawVals of differing types and objectness #767
Conversation
Actually the test here is not exhaustive in the conversion of u8s to Tags. There could be a better test of RawVal::get_tag, but I'll wait for some review before thinking about it more. |
I can reproduce the CI failures. Seems like I've broken something. |
The CI failure was because changing Tag discriminants is ABI-breaking and requires rebuilding the soroban-test-wasms. I tried, but the wasm-workspace does not build presently. Instead I wrote a testcase and simple, possibly temporary, fix and posted a separate pr #773 |
1b96a76
to
1461a54
Compare
Rebased. Still needs #767 to land first. |
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 needs to be panic-free
I removed the panics from Tag::get_scval_type. I also realized that I had other comparison tests located in another module, so I moved the tests from this PR there. |
Also did a rebase to pick up the commits from #773 |
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.
LGTM, thanks!
Edit: I have posted a prerequisite to this patch in #773
What
Make comparison of RawVals agree with comparison of ScVals in the case where one value is an object and one value is a smallval, and they are not the same ScValType.
Also fix an unsoundness in RawVal::get_tag due to incorrect assumptions in an unsafe cast.
Why
Per #743, comparison operations for RawVals and ScVals must agree.
The final fallthrough case of Host::obj_cmp does a comparison based on the Tag discriminant, and the Tag discriminants do not have the same ordering as the ScVal discriminants. This patch adds a method Tag::get_scval_type, and changes obj_cmp to use that instead.
This adds a thorough test case which does an exhaustive conversion between u8s and tags, and an exhaustive match on Tags. The exhaustive match triggered a segfault due to an unsound cast from u8 to Tag in RawVal::get_tag. That function assumed that Tag's discriminants were contiguous between the "marker" discriminants
ObjectCodeLowerBound
andObjectCodeUpperBound
, which was not true. get_tag looks likeIn safe code it may not be possible to trigger the unsoundness - it may require unsafely constructing RawVal. It is not clear to me that contracts can find this code path, but it's probably best to fix it.
I changed the discriminants of Tag to make RawVal::get_tag always correct, and added docs, but the code is brittle to changes. I considered how to make it less error prone and add tests, but could not come up with a better test case than the one that is already in this patch.
This adds a dev-dependency on itertools for the cartesian_product method.
Known limitations
na