Skip to content

Commit 38d6934

Browse files
committed
Allow non-ASCII characters in packet
1 parent e20d15d commit 38d6934

File tree

6 files changed

+41
-18
lines changed

6 files changed

+41
-18
lines changed

src/gdbstub_impl/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -561,9 +561,7 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
561561
) -> Result<HandlerStatus, Error<T::Error, C::Error>> {
562562
match cmd {
563563
Command::Unknown(cmd) => {
564-
// cmd must be ASCII, as the slice originated from a PacketBuf, which checks for
565-
// ASCII as part of the initial validation.
566-
info!("Unknown command: {}", core::str::from_utf8(cmd).unwrap());
564+
info!("Unknown command: {:?}", core::str::from_utf8(cmd));
567565
Ok(HandlerStatus::Handled)
568566
}
569567
// `handle_X` methods are defined in the `ext` module

src/protocol/commands.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use crate::target::Target;
66
pub(self) mod prelude {
77
pub use super::ParseCommand;
88
pub use crate::common::*;
9-
pub use crate::protocol::common::hex::{decode_hex, decode_hex_buf, is_hex, HexString};
9+
pub use crate::protocol::common::hex::{
10+
decode_bin_buf, decode_hex, decode_hex_buf, is_hex, HexString,
11+
};
1012
pub use crate::protocol::common::lists;
1113
pub use crate::protocol::common::thread_id::{
1214
IdKind, SpecificIdKind, SpecificThreadId, ThreadId,

src/protocol/commands/_vFile_pwrite.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ impl<'a> ParseCommand<'a> for vFilePwrite<'a> {
1919
let mut body = body.splitn_mut_no_panic(3, |b| *b == b',');
2020
let fd = decode_hex(body.next()?).ok()?;
2121
let offset = decode_hex_buf(body.next()?).ok()?;
22-
let data = body.next()?;
22+
let data = decode_bin_buf(body.next()?).ok()?;
2323
Some(vFilePwrite{fd, offset, data})
2424
},
2525
_ => None,

src/protocol/common/hex.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,34 @@ pub fn decode_hex_buf(base_buf: &mut [u8]) -> Result<&mut [u8], DecodeHexBufErro
168168
Ok(&mut base_buf[..decoded_len + odd_adust])
169169
}
170170

171-
#[allow(dead_code)]
171+
#[derive(Debug)]
172+
pub enum DecodeBinBufError {
173+
UnexpectedEnd,
174+
}
175+
176+
/// Decode GDB escaped binary bytes into origin bytes _in place_.
177+
pub fn decode_bin_buf(buf: &mut [u8]) -> Result<&mut [u8], DecodeBinBufError> {
178+
use DecodeBinBufError::*;
179+
let mut i = 0;
180+
let mut j = 0;
181+
let len = buf.len();
182+
while i < len {
183+
if buf[i] == b'}' {
184+
if i == len - 1 {
185+
return Err(UnexpectedEnd);
186+
} else {
187+
buf[j] = buf[i + 1] ^ 0x20;
188+
i = i + 1;
189+
}
190+
} else {
191+
buf[j] = buf[i];
192+
}
193+
i = i + 1;
194+
j = j + 1;
195+
}
196+
Ok(&mut buf[..j])
197+
}
198+
172199
#[derive(Debug)]
173200
pub enum EncodeHexBufError {
174201
SmallBuffer,
@@ -268,4 +295,11 @@ mod tests {
268295
let res = decode_hex_buf(&mut payload).unwrap();
269296
assert_eq!(res, [0x1]);
270297
}
298+
299+
#[test]
300+
fn decode_bin_buf_escaped() {
301+
let mut payload = b"}\x03}\x04}]}\n".to_vec();
302+
let res = decode_bin_buf(&mut payload).unwrap();
303+
assert_eq!(res, [0x23, 0x24, 0x7d, 0x2a]);
304+
}
271305
}

src/protocol/packet.rs

-11
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ pub enum PacketParseError {
1010
MissingChecksum,
1111
MalformedChecksum,
1212
MalformedCommand,
13-
NotAscii,
1413
UnexpectedHeader(u8),
1514
}
1615

@@ -57,11 +56,6 @@ impl<'a> PacketBuf<'a> {
5756
.get(..2)
5857
.ok_or(PacketParseError::MalformedChecksum)?;
5958

60-
// validate that the body is valid ASCII
61-
if !body.is_ascii() {
62-
return Err(PacketParseError::NotAscii);
63-
}
64-
6559
// validate the checksum
6660
let checksum = decode_hex(checksum).map_err(|_| PacketParseError::MalformedChecksum)?;
6761
let calculated = body.iter().fold(0u8, |a, x| a.wrapping_add(*x));
@@ -84,11 +78,6 @@ impl<'a> PacketBuf<'a> {
8478
/// the header/checksum trimming stage. ASCII validation is still performed.
8579
#[cfg(test)]
8680
pub fn new_with_raw_body(body: &'a mut [u8]) -> Result<PacketBuf<'a>, PacketParseError> {
87-
// validate the packet is valid ASCII
88-
if !body.is_ascii() {
89-
return Err(PacketParseError::NotAscii);
90-
}
91-
9281
let len = body.len();
9382
Ok(PacketBuf {
9483
buf: body,

src/protocol/response_writer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl<'a, C: Connection + 'a> ResponseWriter<'a, C> {
5454
#[cfg(feature = "std")]
5555
trace!(
5656
"--> ${}#{:02x?}",
57-
core::str::from_utf8(&self.msg).unwrap(), // buffers are always ascii
57+
String::from_utf8_lossy(&self.msg),
5858
checksum
5959
);
6060

0 commit comments

Comments
 (0)