aboutsummaryrefslogtreecommitdiff
path: root/src/rust/tor_util
diff options
context:
space:
mode:
authorIsis Lovecruft <isis@torproject.org>2018-02-06 14:15:33 +0000
committerIsis Lovecruft <isis@torproject.org>2018-02-07 22:51:58 +0000
commitb85436c5961d1b2168c3954a7e718e03a121473f (patch)
tree6b03f9cc9384c31cb17bf4c92bf67c1259e6141d /src/rust/tor_util
parent7ea9e080c58f16fecefa5a0a20406635a2034366 (diff)
downloadtor-b85436c5961d1b2168c3954a7e718e03a121473f.tar.gz
tor-b85436c5961d1b2168c3954a7e718e03a121473f.zip
protover: Fix memleak in Rust impl of protover_compute_for_old_tor.
* FIXES #25127: https://bugs.torproject.org/25127 * ADDS a new module to the Rust tor_util crate for small utilities for working with static strings between languages. * CHANGES the return type of protover_compute_for_old_tor to point to immutable data. * CHANGES the code from the previous commit to use the new static string utilities.
Diffstat (limited to 'src/rust/tor_util')
-rw-r--r--src/rust/tor_util/lib.rs2
-rw-r--r--src/rust/tor_util/strings.rs82
2 files changed, 83 insertions, 1 deletions
diff --git a/src/rust/tor_util/lib.rs b/src/rust/tor_util/lib.rs
index 42fa9d5ad0..12cb3896b6 100644
--- a/src/rust/tor_util/lib.rs
+++ b/src/rust/tor_util/lib.rs
@@ -3,9 +3,9 @@
//! Small module to announce Rust support during startup for demonstration
//! purposes.
-//!
extern crate libc;
extern crate tor_allocate;
pub mod ffi;
+pub mod strings;
diff --git a/src/rust/tor_util/strings.rs b/src/rust/tor_util/strings.rs
new file mode 100644
index 0000000000..9321ce4f85
--- /dev/null
+++ b/src/rust/tor_util/strings.rs
@@ -0,0 +1,82 @@
+// Copyright (c) 2016-2017, The Tor Project, Inc. */
+// See LICENSE for licensing information */
+
+//! Utilities for working with static strings.
+
+use std::ffi::CStr;
+
+/// A byte-array containing a single NUL byte (`b"\0"`).
+pub const NUL_BYTE: &'static [u8] = b"\0";
+
+/// Determine if a byte slice is a C-like string.
+///
+/// These checks guarantee that:
+///
+/// 1. there are no intermediate NUL bytes
+/// 2. the last byte *is* a NUL byte
+///
+/// # Warning
+///
+/// This function does _not_ guarantee that the bytes represent any valid
+/// encoding such as ASCII or UTF-8.
+///
+/// # Examples
+///
+/// ```
+/// # use tor_util::strings::byte_slice_is_c_like;
+/// #
+/// let bytes: &[u8] = b"foo bar baz";
+///
+/// assert!(byte_slice_is_c_like(&bytes) == false);
+///
+/// let bytes: &[u8] = b"foo\0bar baz";
+///
+/// assert!(byte_slice_is_c_like(&bytes) == false);
+///
+/// let bytes: &[u8] = b"foo bar baz\0";
+///
+/// assert!(byte_slice_is_c_like(&bytes) == true);
+/// ```
+pub fn byte_slice_is_c_like(bytes: &[u8]) -> bool {
+ if !bytes[..bytes.len() - 1].contains(&0x00) && bytes[bytes.len() - 1] == 0x00 {
+ return true;
+ }
+ false
+}
+
+/// Get a static `CStr` containing a single `NUL_BYTE`.
+///
+/// # Examples
+///
+/// When used as follows in a Rust FFI function, which could be called
+/// from C:
+///
+/// ```
+/// # extern crate libc;
+/// # extern crate tor_util;
+/// #
+/// # use tor_util::strings::empty_static_cstr;
+/// use libc::c_char;
+/// use std::ffi::CStr;
+///
+/// pub extern "C" fn give_c_code_an_empty_static_string() -> *const c_char {
+/// let empty: &'static CStr = empty_static_cstr();
+///
+/// empty.as_ptr()
+/// }
+///
+/// # fn main() {
+/// # give_c_code_an_empty_static_string();
+/// # }
+/// ```
+///
+/// This equates to an "empty" `const char*` static string in C.
+pub fn empty_static_cstr() -> &'static CStr {
+ let empty: &'static CStr;
+
+ unsafe {
+ empty = CStr::from_bytes_with_nul_unchecked(NUL_BYTE);
+ }
+
+ empty
+}