overdrivenpotato / rust-vst2

VST 2.4 API implementation in rust. Create plugins or hosts.
MIT License
221 stars 23 forks source link

Chunk data is broken. #40

Open monomadic opened 7 years ago

monomadic commented 7 years ago

Chunk data looks like it was never tested. Have been trying for a few hours now and it absolutely is broken, and even older revisions did not work, I have written some isolated examples to prove it.

Here's a simple extraction of the code used to set and restore the vec from the preset data, clearly showing the references point off into space.

use std::os::raw::c_void;

fn main() {
    let chunks = vec![11_u8, 22_u8, 33_u8];
    println!("chunks = {:?}", chunks);
    let len = chunks.len() as isize;
    let ptr: *mut *mut c_void = &mut (chunks.into_boxed_slice().as_ptr() as *mut c_void);
    println!("reading back..");
    let new_chunks = unsafe { std::slice::from_raw_parts(ptr as *mut u8, len as usize) };
    println!("new_chunks = {:?}", new_chunks);
}

This tries to transmute and recover the data from the raw pointer using the same functionality as the code, and I'm getting the same kind of output in the plugin. The size of the array is correct (send independently of ptr) but it points to nothing. example output:

rob@tato ~/P/dd-plugs> rustc test.rs & ./test
chunks = [11, 22, 33]
reading back..
new_chunks = [8, 80, 33]

rob@tato ~/P/dd-plugs> rustc test.rs & ./test
chunks = [11, 22, 33]
reading back..
new_chunks = [8, 80, 129]

Each time returning different numbers (eg. pointers off to random data). Looking at it, I'm not sure how it was supposed to work to begin with, I mean, it seems to be stored as a mut mut c_void pointer to a Box, and recovered as an unboxed slice...?

monomadic commented 7 years ago

I've determined the bug, all of the code was broken in the GetData opcode.

First, the memory was being freed, so you need to mem::forget(chunks) on a vec. It's owned data.

Second, chunks.shrink_to_fit() prevents the need to slice on save.

Third, (ptr as mut mut c_void) = chunks.as_ptr() as mut libc::c_void; works as the actual data assignment to the ptr ref.

I'd PR but I think this repo is kinda dead.

monomadic commented 7 years ago

I'll keep the issue open as it is still a bug...