Skip to content

Commit d1ccf13

Browse files
committed
RSCBC-213: Encoding framing extras unnecessarily allocates a vec
1 parent a894767 commit d1ccf13

File tree

2 files changed

+136
-93
lines changed

2 files changed

+136
-93
lines changed

sdk/couchbase-core/src/memdx/extframe.rs

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -107,46 +107,73 @@ fn iter_ext_frames(buf: &[u8], mut cb: impl FnMut(ExtResFrameCode, &[u8])) -> er
107107
pub fn append_ext_frame(
108108
frame_code: ExtReqFrameCode,
109109
frame_body: &[u8],
110-
buf: &mut Vec<u8>,
110+
buf: &mut [u8],
111+
offset: &mut usize,
111112
) -> error::Result<()> {
112113
let frame_len = frame_body.len();
113114

114-
buf.push(0);
115-
let orig_buf_len = buf.len();
116-
let hdr_byte_ptr = &mut buf[orig_buf_len - 1];
115+
if *offset >= buf.len() {
116+
return Err(Error::new_invalid_argument_error(
117+
"buffer overflow",
118+
"ext frame".to_string(),
119+
));
120+
}
121+
122+
buf[*offset] = 0;
123+
let hdr_byte_ptr = *offset;
124+
*offset += 1;
117125
let u_frame_code: u16 = frame_code.into();
118126

119127
if u_frame_code < 15 {
120-
*hdr_byte_ptr = (*hdr_byte_ptr as u16 | ((u_frame_code & 0x0f) << 4)) as u8;
128+
buf[hdr_byte_ptr] |= ((u_frame_code & 0x0f) << 4) as u8;
121129
} else {
122130
if u_frame_code - 15 >= 15 {
123131
return Err(Error::new_invalid_argument_error(
124132
"ext frame code too large to encode",
125133
"ext frame".to_string(),
126134
));
127135
}
136+
buf[hdr_byte_ptr] |= 0xF0;
128137

129-
*hdr_byte_ptr |= 0xF0;
130-
buf.put_u16(u_frame_code);
138+
if *offset + 2 > buf.len() {
139+
return Err(Error::new_invalid_argument_error(
140+
"buffer overflow",
141+
"ext frame".to_string(),
142+
));
143+
}
144+
buf[*offset..*offset + 2].copy_from_slice(&(u_frame_code.to_be_bytes()));
145+
*offset += 2;
131146
}
132147

133-
let hdr_byte_ptr = &mut buf[orig_buf_len - 1];
134148
if frame_len < 15 {
135-
*hdr_byte_ptr |= (frame_len as u8) & 0xF;
149+
buf[hdr_byte_ptr] |= (frame_len as u8) & 0xF;
136150
} else {
137151
if frame_len - 15 >= 15 {
138152
return Err(Error::new_invalid_argument_error(
139153
"ext frame len too large to encode",
140154
"ext frame".to_string(),
141155
));
142156
}
143-
144-
*hdr_byte_ptr |= 0x0F;
145-
buf.put_u16((frame_len - 15) as u16);
157+
buf[hdr_byte_ptr] |= 0x0F;
158+
if *offset + 2 > buf.len() {
159+
return Err(Error::new_invalid_argument_error(
160+
"buffer overflow",
161+
"ext frame".to_string(),
162+
));
163+
}
164+
buf[*offset..*offset + 2].copy_from_slice(&((frame_len - 15) as u16).to_be_bytes());
165+
*offset += 2;
146166
}
147167

148168
if frame_len > 0 {
149-
buf.extend_from_slice(frame_body);
169+
if *offset + frame_len > buf.len() {
170+
return Err(Error::new_invalid_argument_error(
171+
"buffer overflow",
172+
"ext frame".to_string(),
173+
));
174+
}
175+
buf[*offset..*offset + frame_len].copy_from_slice(frame_body);
176+
*offset += frame_len;
150177
}
151178

152179
Ok(())
@@ -316,25 +343,34 @@ mod tests {
316343

317344
#[test]
318345
fn test_append_preserve_expiry() {
319-
let mut buf = Vec::with_capacity(128);
320-
append_ext_frame(ExtReqFrameCode::PreserveTTL, &[], &mut buf).unwrap();
346+
let mut buf = [0; 128];
347+
let mut offset = 0;
348+
append_ext_frame(ExtReqFrameCode::PreserveTTL, &[], &mut buf, &mut offset).unwrap();
321349

322-
assert_eq!(buf, vec![80]);
350+
assert_eq!(&buf[..offset], &[80]);
323351
}
324352

325353
#[test]
326354
fn test_append_durability_level_no_timeout() {
327-
let mut buf = Vec::with_capacity(128);
328-
append_ext_frame(ExtReqFrameCode::Durability, &[0x01], &mut buf).unwrap();
355+
let mut buf = [0; 128];
356+
let mut offset = 0;
357+
append_ext_frame(ExtReqFrameCode::Durability, &[0x01], &mut buf, &mut offset).unwrap();
329358

330-
assert_eq!(buf, vec![17, 1]);
359+
assert_eq!(&buf[..offset], &[17, 1]);
331360
}
332361

333362
#[test]
334363
fn test_append_durability_level_timeout() {
335-
let mut buf = Vec::with_capacity(128);
336-
append_ext_frame(ExtReqFrameCode::Durability, &[0x01, 0x00, 0x01], &mut buf).unwrap();
364+
let mut buf = [0u8; 128];
365+
let mut offset = 0;
366+
append_ext_frame(
367+
ExtReqFrameCode::Durability,
368+
&[0x01, 0x00, 0x01],
369+
&mut buf,
370+
&mut offset,
371+
)
372+
.unwrap();
337373

338-
assert_eq!(buf, vec![19, 1, 0, 1]);
374+
assert_eq!(&buf[..offset], &[19, 1, 0, 1]);
339375
}
340376
}

0 commit comments

Comments
 (0)