Skip to content

Commit

Permalink
Allow non-ASCII characters in packet
Browse files Browse the repository at this point in the history
  • Loading branch information
bet4it committed Aug 18, 2021
1 parent e20d15d commit 7c03939
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 18 deletions.
4 changes: 1 addition & 3 deletions src/gdbstub_impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,9 +561,7 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
) -> Result<HandlerStatus, Error<T::Error, C::Error>> {
match cmd {
Command::Unknown(cmd) => {
// cmd must be ASCII, as the slice originated from a PacketBuf, which checks for
// ASCII as part of the initial validation.
info!("Unknown command: {}", core::str::from_utf8(cmd).unwrap());
info!("Unknown command: {:?}", core::str::from_utf8(cmd));
Ok(HandlerStatus::Handled)
}
// `handle_X` methods are defined in the `ext` module
Expand Down
4 changes: 3 additions & 1 deletion src/protocol/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use crate::target::Target;
pub(self) mod prelude {
pub use super::ParseCommand;
pub use crate::common::*;
pub use crate::protocol::common::hex::{decode_hex, decode_hex_buf, is_hex, HexString};
pub use crate::protocol::common::hex::{
decode_bin_buf, decode_hex, decode_hex_buf, is_hex, HexString,
};
pub use crate::protocol::common::lists;
pub use crate::protocol::common::thread_id::{
IdKind, SpecificIdKind, SpecificThreadId, ThreadId,
Expand Down
2 changes: 1 addition & 1 deletion src/protocol/commands/_vFile_pwrite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ impl<'a> ParseCommand<'a> for vFilePwrite<'a> {
let mut body = body.splitn_mut_no_panic(3, |b| *b == b',');
let fd = decode_hex(body.next()?).ok()?;
let offset = decode_hex_buf(body.next()?).ok()?;
let data = body.next()?;
let data = decode_bin_buf(body.next()?).ok()?;
Some(vFilePwrite{fd, offset, data})
},
_ => None,
Expand Down
36 changes: 35 additions & 1 deletion src/protocol/common/hex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,34 @@ pub fn decode_hex_buf(base_buf: &mut [u8]) -> Result<&mut [u8], DecodeHexBufErro
Ok(&mut base_buf[..decoded_len + odd_adust])
}

#[allow(dead_code)]
#[derive(Debug)]
pub enum DecodeBinBufError {
UnexpectedEnd,
}

/// Decode GDB escaped binary bytes into origin bytes _in place_.
pub fn decode_bin_buf(buf: &mut [u8]) -> Result<&mut [u8], DecodeBinBufError> {
use DecodeBinBufError::*;
let mut i = 0;
let mut j = 0;
let len = buf.len();
while i < len {
if buf[i] == b'}' {
if i == len - 1 {
return Err(UnexpectedEnd);
} else {
buf[j] = buf[i + 1] ^ 0x20;
i += 1;
}
} else {
buf[j] = buf[i];
}
i += 1;
j += 1;
}
Ok(&mut buf[..j])
}

#[derive(Debug)]
pub enum EncodeHexBufError {
SmallBuffer,
Expand Down Expand Up @@ -268,4 +295,11 @@ mod tests {
let res = decode_hex_buf(&mut payload).unwrap();
assert_eq!(res, [0x1]);
}

#[test]
fn decode_bin_buf_escaped() {
let mut payload = b"}\x03}\x04}]}\n".to_vec();
let res = decode_bin_buf(&mut payload).unwrap();
assert_eq!(res, [0x23, 0x24, 0x7d, 0x2a]);
}
}
11 changes: 0 additions & 11 deletions src/protocol/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pub enum PacketParseError {
MissingChecksum,
MalformedChecksum,
MalformedCommand,
NotAscii,
UnexpectedHeader(u8),
}

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

// validate that the body is valid ASCII
if !body.is_ascii() {
return Err(PacketParseError::NotAscii);
}

// validate the checksum
let checksum = decode_hex(checksum).map_err(|_| PacketParseError::MalformedChecksum)?;
let calculated = body.iter().fold(0u8, |a, x| a.wrapping_add(*x));
Expand All @@ -84,11 +78,6 @@ impl<'a> PacketBuf<'a> {
/// the header/checksum trimming stage. ASCII validation is still performed.
#[cfg(test)]
pub fn new_with_raw_body(body: &'a mut [u8]) -> Result<PacketBuf<'a>, PacketParseError> {
// validate the packet is valid ASCII
if !body.is_ascii() {
return Err(PacketParseError::NotAscii);
}

let len = body.len();
Ok(PacketBuf {
buf: body,
Expand Down
2 changes: 1 addition & 1 deletion src/protocol/response_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl<'a, C: Connection + 'a> ResponseWriter<'a, C> {
#[cfg(feature = "std")]
trace!(
"--> ${}#{:02x?}",
core::str::from_utf8(&self.msg).unwrap(), // buffers are always ascii
String::from_utf8_lossy(&self.msg),
checksum
);

Expand Down

0 comments on commit 7c03939

Please sign in to comment.