-
Notifications
You must be signed in to change notification settings - Fork 799
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
Include a NUL byte in the message returned by wasm_trap_message(). #1947
Conversation
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.
Interesting, I assumed that strings wouldn't be nul-terminated because we pass back a pointer and a length; what was the motivating reason for this change?
wasm.h has this to say:
so I'd guess that wasm_message_t should be NUL terminated but wasm_name_t may not be. In practice it came up in wasm-c-api/examples/start.cc which prints out a string by pointer:
Since it's using a pointer with no length, operator<< calls strlen() to find the end of the string which in turn reads off the end. |
That's good to know! I'd expect this to be a more widespread issue, affecting everywhere |
bors r+ |
👍 |
This PR was actually incorrect. |
`wasm_trap_new` expects a `wasm_message_t`. It's a type alias to `wasm_name_t` with the exception that it represents a null-terminated string. When calling `wasm_trap_new`, no check was present to ensure the string was well-formed. That's a first issue. But in the best scenario, the string was correctly formed and was null-terminated. This string was transformed to a Rust `String` —with the null byte!— and passed to `RuntimeError`. Then in `wasm_trap_message`, another null byte was pushed at the end of the message. It's been introduced in wasmerio#1947. It results in a doubly-null-terminated string, which is incorrect. This patch does the following: 1. It checks that the string given to `wasm_trap_new` contains a null-terminated string or not, and will act accordingly. Note that it's possible to pass a non-null-terminated string, and it will still work because this detail is vicious. The idea is to get a well-formed `RuntimeError` in anycase. * If no null byte is found, the string is passed to `RuntimeError` as a valid Rust string, * If a null byte is found at the end of the string, a new string is passed to `RuntimeError` but without the final null byte, * If a null byte is found but not at the end, it's considered as an error, * If the string contains invalid UTF-8 bytes, it's considered as an error. 2. It updates `wasm_trap_message` to always add a null byte at the end of the returned owned string. 3. It adds test cases when passing a null-terminated or a non-null-terminated string to `wasm_trap_new` and to compare the results to `wasm_trap_message`.
No description provided.