koute/stdweb

Undefined behavior when creating SerializedValue

Badel2 opened this issue · 4 comments

Starting in Rust 1.49, the js serialization crashes at runtime when compiled in release mode. Steps to reproduce:

git clone https://github.com/koute/stdweb
cd stdweb
cd standalone_tests
cargo-web build --release --target=wasm32-unknown-unknown
node target/wasm32-unknown-unknown/release/standalone-tests.js

Output:

wasm://wasm/0008ea5e:232                                                                                                                               
                                                                                             
^                                                                                                                     
                                                                                                                              
RuntimeError: unreachable                                                                                    
    at _ZN3std9panicking20rust_panic_with_hook17hc5713da015ebaa19E (wasm-function[231]:251)                             
    at _ZN3std9panicking19begin_panic_handler28_$u7b$$u7b$closure$u7d$$u7d$17hc5eba7f0030e8f4fE (wasm-function[220]:49)
    at _ZN3std10sys_common9backtrace26__rust_end_short_backtrace17he811f0bd07938b42E (wasm-function[219]:40)                                           
    at rust_begin_unwind (wasm-function[230]:60)                                                                                                       
    at _ZN4core9panicking9panic_fmt17h775d5c012939dd41E (wasm-function[269]:48)                                        
    at _ZN4core9panicking5panic17hf103660e9eaae571E (wasm-function[263]:67)                                                                     
    at _ZN150_$LT$stdweb..webcore..serialization..SerializedValue$u20$as$u20$core..convert..From$LT$stdweb..webcore..serialization..SerializedUntaggedArray$GT$$GT$4from17h27ce91212a6d26c1E.llvm.18112747304485681517 (wasm-function[18]:14)
    at _ZN68_$LT$standalone_tests..utils..Stderr$u20$as$u20$core..fmt..Write$GT$9write_str17hf5f9fc047df287ceE (wasm-function[12]:5)
    at _ZN50_$LT$$RF$mut$u20$W$u20$as$u20$core..fmt..Write$GT$9write_str17h30307225eeedd546E.llvm.4977214982360795154 (wasm-function[14]:5)
    at _ZN4core3fmt5write17hafbb0a7aa3401794E (wasm-function[280]:758)                                                                                 

I bisected the rust compiler and the first bad commit is:

rust-lang/rust@b836329

I guess this is a problem of using std::mem::uninitialized() here:

let mut value: SerializedValue = mem::uninitialized();

I fixed it by using Default::default() instead, and everything works fine:

diff --git a/src/webcore/serialization.rs b/src/webcore/serialization.rs
index 4f97d05..7c8f3e1 100644
--- a/src/webcore/serialization.rs
+++ b/src/webcore/serialization.rs
@@ -412,7 +412,7 @@ macro_rules! untagged_boilerplate {
             #[inline]
             fn from( untagged: $untagged_type ) -> Self {
                 unsafe {
-                    let mut value: SerializedValue = mem::uninitialized();
+                    let mut value: SerializedValue = Default::default();
                     *(&mut value as *mut SerializedValue as *mut $untagged_type) = untagged;
                     value.tag = $tag;
                     value

Alternatively, if you want to avoid initializing with a default value, you could use MaybeUninit which is the type-based way to work with uninitialized data.

riptl commented

Also happens with 1.48 stable

xfbs commented

Is this the same erorr: Issue #9 of yew-wasm-pack-minimal?

#412 looks like it'll fix this (as well as doing various other things)