rustwasm / wasm-bindgen

Facilitating high-level interactions between Wasm modules and JavaScript
https://rustwasm.github.io/docs/wasm-bindgen/
Apache License 2.0
7.78k stars 1.07k forks source link

Getter/setter attribute on functions that take self causes memory access out of bounds. #2168

Open MashPlant opened 4 years ago

MashPlant commented 4 years ago

Steps to Reproduce

It should be easy to reproduce in the simplest context. First create an normal empty wasm-pack project using cargo generate or write it by hand, then write the following code in lib.rs:

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
#[derive(Copy, Clone)]
pub struct Answer(u32);

#[wasm_bindgen]
impl Answer {
  pub fn new() -> Answer { Answer(41) }
  #[wasm_bindgen(getter)]
  pub fn the_answer(self) -> u32 { self.0 + 1 }
}

Then (after some configuration in package.json or something else) in your frontend index.js, write the following code:

import { Answer } from '<the project name>';

let answer = Answer.new();
console.log(answer.the_answer);
console.log(answer.the_answer);

Start it and test in the browser.

Expected Behavior

Like when without #[wasm_bindgen(getter)], reporting null pointer exception:

Error importing `index.js`: Error: null pointer passed to rust

Actual Behavior

You may actually get:

Error importing `index.js`: RuntimeError: memory access out of bounds

According to the experience of other static languages, such memory error cannot always be caught and reported. In another project of mine, I have succeed in fetching trash data using such method, but that context is quite complex and hard to reproduce.

Additional Context

Actually I have fully understood the reason of the bug, the related source code is located at https://github.com/rustwasm/wasm-bindgen/blob/87663c6d2a442d98b3d8ea6242f20c5c21fc0174/crates/cli-support/src/js/mod.rs#L2193 .

Here if the function is marked as a getter/setter, the generated JS won't assign 0 to this.ptr after the call, while the WASM side will free the memory, so here comes the memory access out of bounds

alexcrichton commented 4 years ago

Thanks for the report! I've filed a fix for this at https://github.com/rustwasm/wasm-bindgen/pull/2172

cyk2018 commented 5 months ago

It seems this problem still alive