Skip to content

Commit d9617d3

Browse files
Alexandra Iordachedianpopa
Alexandra Iordache
authored andcommitted
micro-http: unsigned Content-Length...
...and a bunch of fixes for unchecked unsigned arithmetic in connection.rs. Added more unit tests too that exercise failure cases for over/underflows in mathematic operations. Fixes #1977 Signed-off-by: Alexandra Iordache <[email protected]>
1 parent ce26c1a commit d9617d3

File tree

5 files changed

+358
-33
lines changed

5 files changed

+358
-33
lines changed

src/micro_http/src/common/headers.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl Header {
7474
pub struct Headers {
7575
/// The `Content-Length` header field tells us how many bytes we need to receive
7676
/// from the source after the headers.
77-
content_length: i32,
77+
content_length: u32,
7878
/// The `Expect` header field is set when the headers contain the entry "Expect: 100-continue".
7979
/// This means that, per HTTP/1.1 specifications, we must send a response with the status code
8080
/// 100 after we have received the headers in order to receive the body of the request. This
@@ -134,7 +134,7 @@ impl Headers {
134134
}
135135
if let Ok(head) = Header::try_from(entry[0].as_bytes()) {
136136
match head {
137-
Header::ContentLength => match entry[1].trim().parse::<i32>() {
137+
Header::ContentLength => match entry[1].trim().parse::<u32>() {
138138
Ok(content_length) => {
139139
self.content_length = content_length;
140140
Ok(())
@@ -180,7 +180,7 @@ impl Headers {
180180
}
181181

182182
/// Returns the content length of the body.
183-
pub fn content_length(&self) -> i32 {
183+
pub fn content_length(&self) -> u32 {
184184
self.content_length
185185
}
186186

@@ -318,7 +318,7 @@ mod tests {
318318
use super::*;
319319

320320
impl Headers {
321-
pub fn new(content_length: i32, expect: bool, chunked: bool) -> Self {
321+
pub fn new(content_length: u32, expect: bool, chunked: bool) -> Self {
322322
Self {
323323
content_length,
324324
expect,
@@ -471,6 +471,12 @@ mod tests {
471471
assert!(header
472472
.parse_header_line(b"Accept: application/json-patch")
473473
.is_err());
474+
475+
// Invalid content length.
476+
assert_eq!(
477+
header.parse_header_line(b"Content-Length: -1"),
478+
Err(RequestError::InvalidHeader)
479+
);
474480
}
475481

476482
#[test]

src/micro_http/src/common/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ pub mod ascii {
1616
/// Errors associated with parsing the HTTP Request from a u8 slice.
1717
#[derive(Debug, PartialEq)]
1818
pub enum RequestError {
19+
/// No request was pending while the request body was being parsed.
20+
BodyWithoutPendingRequest,
21+
/// No request was pending while the request headers were being parsed.
22+
HeadersWithoutPendingRequest,
1923
/// The HTTP Method is not supported or it is invalid.
2024
InvalidHttpMethod(&'static str),
2125
/// Request URI is invalid.
@@ -37,6 +41,14 @@ pub enum RequestError {
3741
impl Display for RequestError {
3842
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
3943
match self {
44+
Self::BodyWithoutPendingRequest => write!(
45+
f,
46+
"No request was pending while the request body was being parsed."
47+
),
48+
Self::HeadersWithoutPendingRequest => write!(
49+
f,
50+
"No request was pending while the request headers were being parsed."
51+
),
4052
Self::InvalidHttpMethod(inner) => write!(f, "Invalid HTTP Method: {}", inner),
4153
Self::InvalidUri(inner) => write!(f, "Invalid URI: {}", inner),
4254
Self::InvalidHttpVersion(inner) => write!(f, "Invalid HTTP Version: {}", inner),
@@ -298,6 +310,14 @@ mod tests {
298310

299311
#[test]
300312
fn test_display_request_error() {
313+
assert_eq!(
314+
format!("{}", RequestError::BodyWithoutPendingRequest),
315+
"No request was pending while the request body was being parsed."
316+
);
317+
assert_eq!(
318+
format!("{}", RequestError::HeadersWithoutPendingRequest),
319+
"No request was pending while the request headers were being parsed."
320+
);
301321
assert_eq!(
302322
format!("{}", RequestError::InvalidHeader),
303323
"Invalid header."

0 commit comments

Comments
 (0)