Skip to content

Commit 506c189

Browse files
committed
fix: decode chunk string fail
1 parent 1347c28 commit 506c189

File tree

3 files changed

+67
-22
lines changed

3 files changed

+67
-22
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cbor4ii"
3-
version = "1.2.1"
3+
version = "1.2.2"
44
authors = ["quininer <quininer@live.com>"]
55
description = "CBOR: Concise Binary Object Representation"
66
repository = "https://github.com/quininer/cbor4ii"

src/core/dec.rs

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -443,12 +443,38 @@ fn decode_bytes_ref<'de, R: Read<'de>>(num: TypeNum, reader: &mut R)
443443

444444
#[inline]
445445
#[cfg(feature = "use_alloc")]
446-
fn decode_bytes<'a, R: Read<'a>>(num: TypeNum, reader: &mut R, buf: &mut Vec<u8>)
447-
-> Result<Option<&'a [u8]>, Error<R::Error>>
446+
fn decode_bytes_buf<'a, R: Read<'a>>(num: TypeNum, reader: &mut R, len: usize, buf: &mut Vec<u8>)
447+
-> Result<(), Error<R::Error>>
448448
{
449449
const CAP_LIMIT: usize = 16 * 1024;
450450

451-
if let Some(mut len) = decode_len(num, reader)? {
451+
let mut len = len;
452+
buf.reserve(core::cmp::min(len, CAP_LIMIT)); // TODO try_reserve ?
453+
454+
while len != 0 {
455+
let readbuf = reader.fill(len)?;
456+
let readbuf = readbuf.as_ref();
457+
458+
if readbuf.is_empty() {
459+
return Err(Error::eof(num.name, len));
460+
}
461+
462+
let readlen = core::cmp::min(readbuf.len(), len);
463+
464+
buf.extend_from_slice(&readbuf[..readlen]);
465+
reader.advance(readlen);
466+
len -= readlen;
467+
}
468+
469+
Ok(())
470+
}
471+
472+
#[inline]
473+
#[cfg(feature = "use_alloc")]
474+
fn decode_bytes<'a, R: Read<'a>>(num: TypeNum, reader: &mut R, buf: &mut Vec<u8>)
475+
-> Result<Option<&'a [u8]>, Error<R::Error>>
476+
{
477+
if let Some(len) = decode_len(num, reader)? {
452478
// try long lifetime buffer
453479
if let Reference::Long(buf) = reader.fill(len)? {
454480
if buf.len() >= len {
@@ -457,22 +483,7 @@ fn decode_bytes<'a, R: Read<'a>>(num: TypeNum, reader: &mut R, buf: &mut Vec<u8>
457483
}
458484
}
459485

460-
buf.reserve(core::cmp::min(len, CAP_LIMIT)); // TODO try_reserve ?
461-
462-
while len != 0 {
463-
let readbuf = reader.fill(len)?;
464-
let readbuf = readbuf.as_ref();
465-
466-
if readbuf.is_empty() {
467-
return Err(Error::eof(num.name, len));
468-
}
469-
470-
let readlen = core::cmp::min(readbuf.len(), len);
471-
472-
buf.extend_from_slice(&readbuf[..readlen]);
473-
reader.advance(readlen);
474-
len -= readlen;
475-
}
486+
decode_bytes_buf(num, reader, len, buf)?;
476487

477488
Ok(None)
478489
} else {
@@ -486,8 +497,9 @@ fn decode_bytes<'a, R: Read<'a>>(num: TypeNum, reader: &mut R, buf: &mut Vec<u8>
486497

487498
// followed by a series of zero or more strings of
488499
// the specified type ("chunks") that have **definite lengths**
489-
let longbuf = decode_bytes_ref(num, reader)?;
490-
buf.extend_from_slice(longbuf);
500+
let len = decode_len(num, reader)?
501+
.ok_or_else(|| Error::require_length(num.name, None))?;
502+
decode_bytes_buf(num, reader, len, buf)?;
491503
}
492504

493505
Ok(None)

tests/decode.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,3 +423,36 @@ fn test_string_box_vec_maybe() {
423423
}
424424
}
425425
}
426+
427+
#[test]
428+
fn test_mock_chunk_string() {
429+
struct ChunkReader(Vec<u8>, usize);
430+
431+
impl<'de> dec::Read<'de> for ChunkReader {
432+
type Error = std::io::Error;
433+
434+
#[inline]
435+
fn fill<'b>(&'b mut self, _want: usize) -> Result<dec::Reference<'de, 'b>, Self::Error> {
436+
let range = self.1..(self.1+1);
437+
let buf = &self.0[range];
438+
Ok(dec::Reference::Short(buf))
439+
}
440+
441+
#[inline]
442+
fn advance(&mut self, n: usize) {
443+
self.1 += n;
444+
}
445+
}
446+
447+
let mut writer = BufWriter::new(Vec::new());
448+
types::UncheckedStr::unbounded(&mut writer).unwrap();
449+
"123".encode(&mut writer).unwrap();
450+
"456".encode(&mut writer).unwrap();
451+
types::UncheckedStr::end(&mut writer).unwrap();
452+
let buf = writer.into_inner();
453+
454+
let mut reader = ChunkReader(buf, 0);
455+
let s = String::decode(&mut reader).unwrap();
456+
457+
assert_eq!(s, "123456");
458+
}

0 commit comments

Comments
 (0)