Skip to content

Commit 8b06ecd

Browse files
committed
fix: skip invalid UTF-8 headers instead of panicking
Replace `to_str()` with explicit UTF-8 validation in NgxListIterator to handle malformed HTTP headers gracefully.
1 parent 95424ad commit 8b06ecd

File tree

2 files changed

+39
-13
lines changed

2 files changed

+39
-13
lines changed

examples/t/awssig.t

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use strict;
1111

1212
use Test::More;
1313

14+
use Socket qw/ CRLF /;
15+
1416
BEGIN { use FindBin; chdir($FindBin::Bin); }
1517

1618
use lib 'lib';
@@ -21,7 +23,7 @@ use Test::Nginx;
2123
select STDERR; $| = 1;
2224
select STDOUT; $| = 1;
2325

24-
my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(1)
26+
my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(2)
2527
->write_file_expand('nginx.conf', <<"EOF");
2628
2729
%%TEST_GLOBALS%%
@@ -70,4 +72,12 @@ $t->run();
7072
like(http_get('/'), qr/x-authorization: AWS4.*Credential=my-access-key/i,
7173
'awssig header');
7274

75+
like(http(
76+
'GET / HTTP/1.0' . CRLF
77+
. 'Foo: foo' . CRLF
78+
. "Bar: \xFF\xFE\x80\x81" . CRLF
79+
. "Host: localhost" . CRLF . CRLF
80+
), qr/x-authorization: AWS4.*Credential=my-access-key/,
81+
'awssig invalid header ignored');
82+
7383
###############################################################################

src/http/request.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -465,20 +465,36 @@ impl<'a> Iterator for NgxListIterator<'a> {
465465
type Item = (&'a str, &'a str);
466466

467467
fn next(&mut self) -> Option<Self::Item> {
468-
let part = self.part.as_mut()?;
469-
if self.i >= part.arr.len() {
470-
if let Some(next_part_raw) = unsafe { part.raw.next.as_ref() } {
471-
// loop back
472-
*part = next_part_raw.into();
473-
self.i = 0;
474-
} else {
475-
self.part = None;
476-
return None;
468+
loop {
469+
let part = self.part.as_mut()?;
470+
if self.i >= part.arr.len() {
471+
if let Some(next_part_raw) = unsafe { part.raw.next.as_ref() } {
472+
// loop back
473+
*part = next_part_raw.into();
474+
self.i = 0;
475+
} else {
476+
self.part = None;
477+
return None;
478+
}
479+
}
480+
let header = &part.arr[self.i];
481+
self.i += 1;
482+
483+
let key_bytes = header.key.as_ref();
484+
let value_bytes = header.value.as_ref();
485+
486+
match (
487+
std::str::from_utf8(key_bytes),
488+
std::str::from_utf8(value_bytes),
489+
) {
490+
(Ok(key), Ok(value)) => {
491+
return Some((key, value));
492+
}
493+
_ => {
494+
continue;
495+
}
477496
}
478497
}
479-
let header = &part.arr[self.i];
480-
self.i += 1;
481-
Some((header.key.to_str(), header.value.to_str()))
482498
}
483499
}
484500

0 commit comments

Comments
 (0)