koute / stdweb

A standard library for the client-side Web
Apache License 2.0
3.44k stars 177 forks source link

Strange memory corruption when using repeated calls to set_text_content and KeyDownEvent #302

Open liamnaddell opened 5 years ago

liamnaddell commented 5 years ago
#[macro_use]
extern crate stdweb;
use stdweb::web::window;
use stdweb::web::event::KeyDownEvent;
use stdweb::web::IEventTarget;
use stdweb::traits::IKeyboardEvent;
use stdweb::web::document;
use stdweb::web::INode;

const motd: &'static str = "root@localhost ~$ ";
fn main() {
    stdweb::initialize();
    let elem = document().create_element("pre").unwrap();
    elem.set_text_content(&motd);
    document().body().unwrap().append_child(&elem);
     window().add_event_listener( move |e: KeyDownEvent| {

        let val = get_val(e);
        let mut cval = elem.text_content().unwrap();
        if val == "Backspace" {
            panic!();
            let c = cval.pop().unwrap_or(0 as char);

            if c.to_string() == "\n" {
                cval.push(c);
            } else {
                elem.set_text_content(&cval);
            }

        } else if val == "\n" {
            cval+=&val;
            cval+=&motd;
            elem.set_text_content(&cval);

        } else if val == "Shift" {
            panic!();
        } else {
            elem.set_text_content(&(cval+&val));
        }
     });

    stdweb::event_loop();
}
fn get_val(e: KeyDownEvent) -> String  {
    match e.key().as_ref() {
        "Enter" => String::from("\n"),
        "Alt" | "AltGr"| "CapsLock"| "Control"| "Function"| "FunctionLock"| "Hyper"| "Meta"| "NumLock"| "OS"| "ScrollLock"| "Shift"| "Super"| "Symbol"| "SymbolLock" => String::from(""),
        _ => e.key().to_string(),

This code is supposed to produce a simple command line interface on the web. If you type "Hello World\<Enter>", then "H "(note the space) the code panics with "index out of bounds"

This screams memory corruption.

Rules. This error is mildly reproducible if you type "\<any letter>ello World!\n\<the exact same letter from earlier> "

liamnaddell commented 5 years ago

Sometimes this error just occurs randomly too when typing capital letters, spaces and lowercase letters

koute commented 5 years ago

Thanks a lot for the report!

I haven't yet debugged this fully, but I've managed to reduce the issue to this form:

#[macro_use]
extern crate stdweb;
use stdweb::unstable::TryInto;

fn main() {
    stdweb::initialize();

    let cb = move || {
        let val: stdweb::Value = String::from( "a" ).into();
        let val: String = val.into_string().unwrap().to_string();

        let cval: String = js! { return "root@localhost ~$ aa"; }.try_into().unwrap();
        println!( "{}", cval );
        let x = &(cval+&val);
    };

    js! {
        @{cb}();
    }
}

Running cargo web build && node target/asmjs-unknown-emscripten/debug/foobar.js I get:

root@localhost ~$ aa
warning: build with  -s DEMANGLE_SUPPORT=1  to link in libcxxabi demangling
exception thrown: abort() at Error
    at jsStackTrace (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:1470:13)
    at stackTrace (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:1487:12)
    at Object.abort (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:50174:44)
    at _abort (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:5415:22)
    at _free (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:46331:7)
    at ___rdl_dealloc (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:26970:2)
    at ___rust_dealloc (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:10657:2)
    at __ZN5alloc5alloc7dealloc17hde0c8de686cb10c1E (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:18388:2)
    at __ZN59__LT_alloc__alloc__Global_u20_as_u20_core__alloc__Alloc_GT_7dealloc17h5999a3577cb029beE (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:18370:2)
    at __ZN49__LT_alloc__raw_vec__RawVec_LT_T_C__u20_A_GT__GT_14dealloc_buffer17h061541c4b112454cE (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:16691:2)

/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:537
      throw ex;
      ^
abort() at Error
    at jsStackTrace (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:1470:13)
    at stackTrace (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:1487:12)
    at Object.abort (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:50174:44)
    at _abort (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:5415:22)
    at _free (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:46331:7)
    at ___rdl_dealloc (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:26970:2)
    at ___rust_dealloc (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:10657:2)
    at __ZN5alloc5alloc7dealloc17hde0c8de686cb10c1E (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:18388:2)
    at __ZN59__LT_alloc__alloc__Global_u20_as_u20_core__alloc__Alloc_GT_7dealloc17h5999a3577cb029beE (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:18370:2)
    at __ZN49__LT_alloc__raw_vec__RawVec_LT_T_C__u20_A_GT__GT_14dealloc_buffer17h061541c4b112454cE (/tmp/foobar/target/asmjs-unknown-emscripten/debug/foobar.js:16691:2)

Definitely looks like some sort of memory corruption.