Skip to content
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

Decoder iterator returns next() when can't decode full object #6

Closed
tailhook opened this issue Sep 7, 2015 · 6 comments
Closed

Decoder iterator returns next() when can't decode full object #6

tailhook opened this issue Sep 7, 2015 · 6 comments

Comments

@tailhook
Copy link

tailhook commented Sep 7, 2015

I use the following code to unpack a packet from network:

  let mut dec = Decoder::from_reader(io::Cursor::new(buf));
  match dec.decode::<Packet>().next() {...}

And next() returns None when packet was truncated by some reason. Is it works as intended? I would like to have some more explicit error.

I use cbor 0.3.14 if that matters.

Is there a better interface? Should this behavior be documented?

@BurntSushi
Copy link
Owner

It returns none if there's no more data to decode IIRC. It returns an error if there was a problem decoding.

I'm not sure what specifically is going wrong in your case because I don't see enough details to be able to reproduce your problem. Could you please provide a minimal code sample that I can run that demonstrates your problem? Thanks.

@tailhook
Copy link
Author

tailhook commented Sep 7, 2015

Okay, the problem is two-fold. Here is the code:

use std::io::Write;
extern crate bytes;
extern crate cbor;
extern crate rustc_serialize;

use cbor::{Encoder, Decoder};

#[derive(RustcDecodable, RustcEncodable, Debug)]
struct Test {
    value: String,
}

fn main() {
    let mut buf = bytes::ByteBuf::mut_with_capacity(16);
    {
        let mut enc = Encoder::from_writer(&mut buf);
        enc.encode(&[Test {
            value: "hello world hello world hello world".to_string()
        }]).unwrap();
    }
    println!("RESULT len: {}, contents: {:?}", buf.bytes().len(), buf.bytes());
    let mut reader = buf.flip();
    let mut dec = Decoder::from_reader(&mut reader);
    println!("Decoded: {:?}", dec.decode::<Test>().next());
}

For small buffer size it returns:

RESULT len: 16, contents: [161, 101, 118, 97, 108, 117, 101, 120, 35, 104, 101, 108, 108, 111, 32, 119]
Decoded: None

When I change CAPACITY to 64 it outputs the following:

RESULT len: 44, contents: [161, 101, 118, 97, 108, 117, 101, 120, 35, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 32, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 32, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
Decoded: Some(Ok(Test { value: "hello world hello world hello world" }))

(If you wonder if bytes::ByteBuf may have issue, the reading part works the same with Cursor, and writer part returns error Err(Error { repr: Custom(Custom { kind: WriteZero, error: StringError("failed to write whole buffer") }) }), when data is truncated)

@BurntSushi
Copy link
Owner

Nice find! I've fixed this and uploaded a new release of CBOR to crates.io (0.3.16).

@tailhook
Copy link
Author

tailhook commented Sep 7, 2015

Great! Thanks for quick response.

Still in this example encoding silently truncates value. Should I file a separate issue for this?

@BurntSushi
Copy link
Owner

The example where you set the capacity to 16? I don't see how that's an issue with cbor. Are you sure that ByteBuf is a growable buffer? I don't see any documentation for the ByteBuf type (and I admit, I don't know what problems the bytes crate is trying to solve), so I'm not sure what the semantics should be.

If you replace your buffer with io::Cursor::new(vec![]) then things work (because Cursor will grow the underlying buffer if possible, which is the case with Vec).

@tailhook
Copy link
Author

tailhook commented Sep 7, 2015

No, the buffer is intentionally not growable. But when I try to write_all for more that allowed bytes I get the following error:

Err(Error { repr: Custom(Custom { kind: WriteZero, error: StringError("failed to write whole buffer") }) })

Which I expect to be propagated by encoder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants