-
-
Notifications
You must be signed in to change notification settings - Fork 416
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 is_null_terminated reading arbitrary memory (issue #1425) #1429
Conversation
When `_alloc` is equal to `_size` the `is_null_terminated` method will point to arbitrary memory when checking for the `0` byte. This PR makes that method first check that `_alloc != _size` before reading the `_size` byte of the `Pointer[U8]`.
It seems like there's an assumption in the library (at least sometimes) that the first If this is consistent, then perhaps |
Thank you! Can you also add a test case that highlights the fixed case? |
@jemc Tests added, though it occurs to me now that instead of this: (_alloc > 0) and (_alloc != _size) and (_ptr._apply(_size) == 0) we could probably do this: (_alloc != _size) and (_ptr._apply(_size) == 0) ...since when they're not equal, |
Appveyor has failed, travis is still running. The tests passed on my Linux box. I changed the test case to no longer use a power of two length array. I don't know why that would make a difference, unless an array literal automatically allocates to the next power of two. I'll add the power of two array test back in to see if it passes. EDIT: So it appears that an array literal does pre-allocate up to (presumably) the next power of two when it is not itself a power of two size. The tests have been updated to reflect this. EDIT: Well jeepers, this test fails no matter what I do... h.assert_true(String.from_iso_array(recover
['a', 'b', 'c']
end).is_null_terminated()) Looks like I'm just born to lose. I'm going to reverse it back to |
Tests that were previously added that create a String from a non-power-of-two sized array literal were failing, so this adds a test with a power-of-two sized array to see if it is not null termianted.
The `is_null_terminated` tests that test the from_iso_array strings have been updated to reflect the apparent reality of preallocation that takes place when the length of the length of the array literal is not a power of two. It appears as though the array does get pre-allocated with zero bytes up to the next power of two, and as such, is null-terminated.
Well shucks. **** FAILED: builtin/String.is_null_terminated C:\projects\ponyc\packages\builtin_test\_test.pony:439: Assert true failed. **** FAILED: builtin/String.is_null_terminated C:\projects\ponyc\packages\builtin_test\_test.pony:439: Assert false failed. I'm going to remove that test to see if it passes with only the one test. The test is in my comment above for quick reference. |
The test is inconsistent because allocated memory isn't set to zero in release mode. |
Ah, I was going to ask if that preallocation was zeroed. So then the only way that's going to work is if the first pre-allocated bit gets zeroed consistently. I have no idea how to do that for the literals. (EDIT: Oh wait, that's array literals. Nevermind.) Looks like that's missing in |
PR #1436 sets the null byte in |
It's been merged. Thanks! |
This test was previously failing because of incorrect behavior of `String.from_iso_array`, described in #1435, which has since been fixed.
Thanks @jemc, looks like everything passes. |
When
_alloc
is equal to_size
, theis_null_terminated
method willpoint to arbitrary memory when checking for the
0
byte. This PR makesthat method first check that
_alloc != _size
before reading the_size
byte of thePointer[U8]
.Fixes #1425