Skip to content

Commit

Permalink
check frame empty (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
pythcoiner authored Oct 9, 2024
1 parent f8304bf commit 0870110
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 2 deletions.
13 changes: 12 additions & 1 deletion src/codec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ impl TryFrom<&[u8]> for ExceptionResponse {
type Error = Error;

fn try_from(bytes: &[u8]) -> Result<Self> {
if bytes.is_empty() {
return Err(Error::BufferSize);
}
let fn_err_code = bytes[0];
if fn_err_code < 0x80 {
return Err(Error::ExceptionFnCode(fn_err_code));
Expand Down Expand Up @@ -156,7 +159,9 @@ impl<'r> TryFrom<&'r [u8]> for Response<'r> {

fn try_from(bytes: &'r [u8]) -> Result<Self> {
use FunctionCode as F;

if bytes.is_empty() {
return Err(Error::BufferSize);
}
let fn_code = bytes[0];
if bytes.len() < min_response_pdu_len(FunctionCode::new(fn_code)) {
return Err(Error::BufferSize);
Expand Down Expand Up @@ -327,6 +332,9 @@ impl<'r> Encode for RequestPdu<'r> {

impl<'r> Encode for ResponsePdu<'r> {
fn encode(&self, buf: &mut [u8]) -> Result<usize> {
if buf.is_empty() {
return Err(Error::BufferSize);
}
match self.0 {
Ok(res) => res.encode(buf),
Err(e) => e.encode(buf),
Expand All @@ -336,6 +344,9 @@ impl<'r> Encode for ResponsePdu<'r> {

impl Encode for ExceptionResponse {
fn encode(&self, buf: &mut [u8]) -> Result<usize> {
if buf.is_empty() {
return Err(Error::BufferSize);
}
let [code, ex]: [u8; 2] = (*self).into();
buf[0] = code;
buf[1] = ex;
Expand Down
8 changes: 8 additions & 0 deletions src/codec/rtu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ pub fn decode(
use DecoderType::{Request, Response};
let mut drop_cnt = 0;

if buf.is_empty() {
return Err(Error::BufferSize);
}

loop {
let mut retry = false;
if drop_cnt + 1 >= buf.len() {
Expand Down Expand Up @@ -89,6 +93,10 @@ pub fn decode(
/// Extract a PDU frame out of a buffer.
#[allow(clippy::similar_names)]
pub fn extract_frame(buf: &[u8], pdu_len: usize) -> Result<Option<DecodedFrame>> {
if buf.is_empty() {
return Err(Error::BufferSize);
}

let adu_len = 1 + pdu_len;
if buf.len() >= adu_len + 2 {
let (adu_buf, buf) = buf.split_at(adu_len);
Expand Down
3 changes: 3 additions & 0 deletions src/codec/rtu/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use super::*;

/// Decode an RTU request.
pub fn decode_request(buf: &[u8]) -> Result<Option<RequestAdu>> {
if buf.is_empty() {
return Ok(None);
}
decode(DecoderType::Request, buf)
.and_then(|frame| {
let Some((DecodedFrame { slave, pdu }, _frame_pos)) = frame else {
Expand Down
7 changes: 7 additions & 0 deletions src/codec/tcp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ pub fn decode(
use DecoderType::{Request, Response};
let mut drop_cnt = 0;

if buf.is_empty() {
return Err(Error::BufferSize);
}

loop {
let mut retry = false;
if drop_cnt + 1 >= buf.len() {
Expand Down Expand Up @@ -90,6 +94,9 @@ pub fn decode(

/// Extract a PDU frame out of a buffer.
pub fn extract_frame(buf: &[u8], pdu_len: usize) -> Result<Option<DecodedFrame>> {
if buf.is_empty() {
return Err(Error::BufferSize);
}
let adu_len = 7 + pdu_len;
if buf.len() >= adu_len {
let (adu_buf, _next_frame) = buf.split_at(adu_len);
Expand Down
6 changes: 6 additions & 0 deletions src/codec/tcp/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use super::*;

/// Decode an TCP request.
pub fn decode_request(buf: &[u8]) -> Result<Option<RequestAdu>> {
if buf.is_empty() {
return Ok(None);
}
let frame = decode(DecoderType::Request, buf)?;
let Some((decoded_frame, _frame_pos)) = frame else {
return Ok(None);
Expand Down Expand Up @@ -31,6 +34,9 @@ pub fn decode_request(buf: &[u8]) -> Result<Option<RequestAdu>> {

// Decode a TCP response
pub fn decode_response(buf: &[u8]) -> Result<Option<ResponseAdu>> {
if buf.is_empty() {
return Err(Error::BufferSize);
}
decode(DecoderType::Response, buf)
.and_then(|frame| {
let Some((decoded_frame, _frame_pos)) = frame else {
Expand Down
3 changes: 3 additions & 0 deletions src/frame/coils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ pub struct Coils<'c> {
impl<'c> Coils<'c> {
/// Pack coils defined by an bool slice into a byte buffer.
pub fn from_bools(bools: &[bool], target: &'c mut [u8]) -> Result<Self, Error> {
if bools.is_empty() {
return Err(Error::BufferSize);
}
pack_coils(bools, target)?;
Ok(Coils {
data: target,
Expand Down
2 changes: 1 addition & 1 deletion src/frame/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub struct Data<'d> {
impl<'d> Data<'d> {
/// Pack words (u16 values) into a byte buffer.
pub fn from_words(words: &[u16], target: &'d mut [u8]) -> Result<Self, Error> {
if words.len() * 2 > target.len() {
if (words.len() * 2 > target.len()) || words.is_empty() {
return Err(Error::BufferSize);
}
for (i, w) in words.iter().enumerate() {
Expand Down

0 comments on commit 0870110

Please sign in to comment.