Skip to content

Commit 90870f3

Browse files
committed
Fix stack overflow in BufVecDeque impl
1 parent 87019df commit 90870f3

File tree

1 file changed

+22
-22
lines changed

1 file changed

+22
-22
lines changed

httpbis/src/bytes_ext/buf_vec_deque.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::cmp;
12
use std::collections::vec_deque;
23
use std::collections::VecDeque;
34
use std::io::IoSlice;
@@ -7,6 +8,7 @@ use std::ops::DerefMut;
78

89
use bytes::Buf;
910
use bytes::Bytes;
11+
use bytes::BytesMut;
1012

1113
use crate::bytes_ext::buf_get_bytes::BufGetBytes;
1214

@@ -117,8 +119,8 @@ impl<B: Buf> Buf for BufVecDeque<B> {
117119
fn copy_to_bytes(&mut self, cnt: usize) -> Bytes {
118120
assert!(cnt <= self.remaining());
119121

120-
match self.deque.front_mut() {
121-
Some(front) if front.remaining() >= cnt => {
122+
if let Some(front) = self.deque.front_mut() {
123+
if front.remaining() >= cnt {
122124
let r = if front.remaining() == cnt {
123125
let mut front = self.deque.pop_front().unwrap();
124126
front.copy_to_bytes(cnt)
@@ -127,33 +129,31 @@ impl<B: Buf> Buf for BufVecDeque<B> {
127129
};
128130

129131
self.len -= cnt;
130-
r
132+
return r;
131133
}
132-
Some(_) => self.take(cnt).copy_to_bytes(cnt),
133-
None => Bytes::new(),
134134
}
135+
136+
let mut bytes = BytesMut::with_capacity(cnt);
137+
while bytes.len() < cnt {
138+
let need = cnt - bytes.len();
139+
let front = self.deque.front_mut().unwrap();
140+
let copy = cmp::min(front.chunk().len(), need);
141+
bytes.extend_from_slice(&front.chunk()[..copy]);
142+
front.advance(copy);
143+
if !front.has_remaining() {
144+
let front = self.deque.pop_front().unwrap();
145+
assert!(!front.has_remaining());
146+
}
147+
self.len -= copy;
148+
}
149+
assert_eq!(bytes.len(), cnt);
150+
bytes.freeze()
135151
}
136152
}
137153

138154
impl<B: BufGetBytes> BufGetBytes for BufVecDeque<B> {
139155
fn get_bytes(&mut self, cnt: usize) -> Bytes {
140-
assert!(cnt <= self.remaining());
141-
142-
match self.deque.front_mut() {
143-
Some(front) if front.remaining() >= cnt => {
144-
let r = if front.remaining() == cnt {
145-
let mut front = self.deque.pop_front().unwrap();
146-
front.get_bytes(cnt)
147-
} else {
148-
front.get_bytes(cnt)
149-
};
150-
151-
self.len -= cnt;
152-
r
153-
}
154-
Some(_) => self.take(cnt).copy_to_bytes(cnt),
155-
None => Bytes::new(),
156-
}
156+
self.copy_to_bytes(cnt)
157157
}
158158
}
159159

0 commit comments

Comments
 (0)