Skip to content

Commit 0afa1af

Browse files
committed
ngx_str_t::to_str should not unwrap.
In general, we should avoid exposing methods that panic when its reasonable to return a Result instead. This particular method was used, likely without considering that it may panic or validating that the contents are utf-8, in ngx::http::NgxListIterator's Iterator impl, which made it very easy to panic based on untrusted input.
1 parent fcb28a7 commit 0afa1af

File tree

4 files changed

+37
-16
lines changed

4 files changed

+37
-16
lines changed

examples/async.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ use ngx::ffi::{
99
ngx_array_push, ngx_command_t, ngx_conf_t, ngx_connection_t, ngx_event_t, ngx_http_handler_pt,
1010
ngx_http_module_t, ngx_http_phases_NGX_HTTP_ACCESS_PHASE, ngx_int_t, ngx_module_t,
1111
ngx_post_event, ngx_posted_events, ngx_posted_next_events, ngx_str_t, ngx_uint_t,
12-
NGX_CONF_TAKE1, NGX_HTTP_LOC_CONF, NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_MODULE,
12+
NGX_CONF_TAKE1, NGX_HTTP_LOC_CONF, NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_MODULE, NGX_LOG_EMERG,
1313
};
1414
use ngx::http::{self, HttpModule, MergeConfigError};
1515
use ngx::http::{HttpModuleLocationConf, HttpModuleMainConf, NgxHttpCoreModule};
16-
use ngx::{http_request_handler, ngx_log_debug_http, ngx_string};
16+
use ngx::{http_request_handler, ngx_conf_log_error, ngx_log_debug_http, ngx_string};
1717
use tokio::runtime::Runtime;
1818

1919
struct Module;
@@ -205,7 +205,13 @@ extern "C" fn ngx_http_async_commands_set_enable(
205205
unsafe {
206206
let conf = &mut *(conf as *mut ModuleConfig);
207207
let args: &[ngx_str_t] = (*(*cf).args).as_slice();
208-
let val = args[1].to_str();
208+
let val = match args[1].to_str() {
209+
Ok(s) => s,
210+
Err(_) => {
211+
ngx_conf_log_error!(NGX_LOG_EMERG, cf, "`async` argument is not utf-8 encoded");
212+
return ngx::core::NGX_CONF_ERROR;
213+
}
214+
};
209215

210216
// set default value optionally
211217
conf.enable = false;

examples/awssig.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use ngx::ffi::{
66
ngx_array_push, ngx_command_t, ngx_conf_t, ngx_http_handler_pt, ngx_http_module_t,
77
ngx_http_phases_NGX_HTTP_PRECONTENT_PHASE, ngx_int_t, ngx_module_t, ngx_str_t, ngx_uint_t,
88
NGX_CONF_TAKE1, NGX_HTTP_LOC_CONF, NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_MODULE,
9-
NGX_HTTP_SRV_CONF,
9+
NGX_HTTP_SRV_CONF, NGX_LOG_EMERG,
1010
};
1111
use ngx::http::*;
12-
use ngx::{http_request_handler, ngx_log_debug_http, ngx_string};
12+
use ngx::{http_request_handler, ngx_conf_log_error, ngx_log_debug_http, ngx_string};
1313

1414
struct Module;
1515

@@ -176,7 +176,17 @@ extern "C" fn ngx_http_awssigv4_commands_set_enable(
176176
unsafe {
177177
let conf = &mut *(conf as *mut ModuleConfig);
178178
let args: &[ngx_str_t] = (*(*cf).args).as_slice();
179-
let val = args[1].to_str();
179+
let val = match args[1].to_str() {
180+
Ok(s) => s,
181+
Err(_) => {
182+
ngx_conf_log_error!(
183+
NGX_LOG_EMERG,
184+
cf,
185+
"`awssigv4` argument is not utf-8 encoded"
186+
);
187+
return ngx::core::NGX_CONF_ERROR;
188+
}
189+
};
180190

181191
// set default value optionally
182192
conf.enable = false;

examples/curl.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ use ngx::core;
44
use ngx::ffi::{
55
ngx_array_push, ngx_command_t, ngx_conf_t, ngx_http_handler_pt, ngx_http_module_t,
66
ngx_http_phases_NGX_HTTP_ACCESS_PHASE, ngx_int_t, ngx_module_t, ngx_str_t, ngx_uint_t,
7-
NGX_CONF_TAKE1, NGX_HTTP_LOC_CONF, NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_MODULE,
7+
NGX_CONF_TAKE1, NGX_HTTP_LOC_CONF, NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_MODULE, NGX_LOG_EMERG,
88
};
99
use ngx::http::{self, HttpModule, MergeConfigError};
1010
use ngx::http::{HttpModuleLocationConf, HttpModuleMainConf, NgxHttpCoreModule};
11-
use ngx::{http_request_handler, ngx_log_debug_http, ngx_string};
11+
use ngx::{http_request_handler, ngx_conf_log_error, ngx_log_debug_http, ngx_string};
1212

1313
struct Module;
1414

@@ -119,7 +119,13 @@ extern "C" fn ngx_http_curl_commands_set_enable(
119119
let conf = &mut *(conf as *mut ModuleConfig);
120120
let args: &[ngx_str_t] = (*(*cf).args).as_slice();
121121

122-
let val = args[1].to_str();
122+
let val = match args[1].to_str() {
123+
Ok(s) => s,
124+
Err(_) => {
125+
ngx_conf_log_error!(NGX_LOG_EMERG, cf, "`curl` argument is not utf-8 encoded");
126+
return ngx::core::NGX_CONF_ERROR;
127+
}
128+
};
123129

124130
// set default value optionally
125131
conf.enable = false;

nginx-sys/src/string.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,14 @@ impl ngx_str_t {
4040
self.len == 0
4141
}
4242

43-
/// Convert the nginx string to a string slice (`&str`).
44-
///
45-
/// # Panics
46-
/// This function panics if the `ngx_str_t` is not valid UTF-8.
43+
/// Returns the contents of this `ngx_str_t` a string slice (`&str`) if
44+
/// the contents are utf-8 encoded.
4745
///
4846
/// # Returns
49-
/// A string slice (`&str`) representing the nginx string.
50-
pub fn to_str(&self) -> &str {
51-
str::from_utf8(self.as_bytes()).unwrap()
47+
/// A string slice (`&str`) representing the nginx string, or else a
48+
/// Utf8Error.
49+
pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
50+
str::from_utf8(self.as_bytes())
5251
}
5352

5453
/// Creates an empty `ngx_str_t` instance.

0 commit comments

Comments
 (0)