use cstr crate rather than unsafe
This removes a few uses of unsafe, and it verifies statically that there are no interior NUL bytes.
This commit is contained in:
parent
06d7815f9c
commit
13b192949d
|
@ -287,6 +287,24 @@ dependencies = [
|
||||||
"subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cstr"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cstr-macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cstr-macros"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cursive"
|
name = "cursive"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
|
@ -941,6 +959,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cstr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -981,6 +1000,7 @@ dependencies = [
|
||||||
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cstr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cursive 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cursive 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"docopt 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1296,6 +1316,11 @@ dependencies = [
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "procedural-masquerade"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "protobuf"
|
name = "protobuf"
|
||||||
version = "3.0.0-pre"
|
version = "3.0.0-pre"
|
||||||
|
@ -2370,6 +2395,8 @@ dependencies = [
|
||||||
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
|
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
|
||||||
"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
|
"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
|
||||||
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
||||||
|
"checksum cstr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "19f7a08ed4ecd7e077d4cee63937473e6f7cf57b702a9114ef41751b2cbc0f60"
|
||||||
|
"checksum cstr-macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0f12dd847ec773fc98d75edba5394cb87d0f35e7ee548a4c81849ca6374b3d48"
|
||||||
"checksum cursive 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b7ecc7282b5361471b607c26f44148205607e26d48a2fc65bd16e7619b1ebb78"
|
"checksum cursive 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b7ecc7282b5361471b607c26f44148205607e26d48a2fc65bd16e7619b1ebb78"
|
||||||
"checksum darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfbcb0c5961907597a7d1148e3af036268f2b773886b8bb3eeb1e1281d3d3d6"
|
"checksum darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfbcb0c5961907597a7d1148e3af036268f2b773886b8bb3eeb1e1281d3d3d6"
|
||||||
"checksum darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6afc018370c3bff3eb51f89256a6bdb18b4fdcda72d577982a14954a7a0b402c"
|
"checksum darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6afc018370c3bff3eb51f89256a6bdb18b4fdcda72d577982a14954a7a0b402c"
|
||||||
|
@ -2472,6 +2499,7 @@ dependencies = [
|
||||||
"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
|
"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
|
||||||
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
|
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
|
||||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||||
|
"checksum procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9a1574a51c3fd37b26d2c0032b649d08a7d51d4cca9c41bbc5bf7118fa4509d0"
|
||||||
"checksum protobuf 3.0.0-pre (git+https://github.com/stepancheg/rust-protobuf)" = "<none>"
|
"checksum protobuf 3.0.0-pre (git+https://github.com/stepancheg/rust-protobuf)" = "<none>"
|
||||||
"checksum protobuf-codegen 3.0.0-pre (git+https://github.com/stepancheg/rust-protobuf)" = "<none>"
|
"checksum protobuf-codegen 3.0.0-pre (git+https://github.com/stepancheg/rust-protobuf)" = "<none>"
|
||||||
"checksum protobuf-codegen-pure 3.0.0-pre (git+https://github.com/stepancheg/rust-protobuf)" = "<none>"
|
"checksum protobuf-codegen-pure 3.0.0-pre (git+https://github.com/stepancheg/rust-protobuf)" = "<none>"
|
||||||
|
|
|
@ -22,6 +22,7 @@ base = { package = "moonfire-base", path = "base" }
|
||||||
base64 = "0.10.0"
|
base64 = "0.10.0"
|
||||||
bytes = "0.4.6"
|
bytes = "0.4.6"
|
||||||
byteorder = "1.0"
|
byteorder = "1.0"
|
||||||
|
cstr = "0.1.7"
|
||||||
cursive = "0.12"
|
cursive = "0.12"
|
||||||
db = { package = "moonfire-db", path = "db" }
|
db = { package = "moonfire-db", path = "db" }
|
||||||
docopt = "1.0"
|
docopt = "1.0"
|
||||||
|
|
|
@ -15,6 +15,7 @@ path = "lib.rs"
|
||||||
base = { package = "moonfire-base", path = "../base" }
|
base = { package = "moonfire-base", path = "../base" }
|
||||||
base64 = "0.10.0"
|
base64 = "0.10.0"
|
||||||
blake2-rfc = "0.2.18"
|
blake2-rfc = "0.2.18"
|
||||||
|
cstr = "0.1.7"
|
||||||
failure = "0.1.1"
|
failure = "0.1.1"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
lazy_static = "1.0"
|
lazy_static = "1.0"
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
//! This includes opening files for serving, rotating away old files, and saving new files.
|
//! This includes opening files for serving, rotating away old files, and saving new files.
|
||||||
|
|
||||||
use crate::db::CompositeId;
|
use crate::db::CompositeId;
|
||||||
|
use cstr::*;
|
||||||
use failure::{Error, Fail, bail, format_err};
|
use failure::{Error, Fail, bail, format_err};
|
||||||
use libc::c_char;
|
use libc::c_char;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
@ -140,7 +141,7 @@ pub(crate) unsafe fn renameat(from_fd: &Fd, from_path: *const c_char,
|
||||||
/// Reads `dir`'s metadata. If none is found, returns an empty proto.
|
/// Reads `dir`'s metadata. If none is found, returns an empty proto.
|
||||||
pub(crate) fn read_meta(dir: &Fd) -> Result<schema::DirMeta, Error> {
|
pub(crate) fn read_meta(dir: &Fd) -> Result<schema::DirMeta, Error> {
|
||||||
let mut meta = schema::DirMeta::default();
|
let mut meta = schema::DirMeta::default();
|
||||||
let p = unsafe { ffi::CStr::from_ptr("meta\0".as_ptr() as *const c_char) };
|
let p = cstr!("meta");
|
||||||
let mut f = match unsafe { dir.openat(p.as_ptr(), libc::O_RDONLY, 0) } {
|
let mut f = match unsafe { dir.openat(p.as_ptr(), libc::O_RDONLY, 0) } {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if e.kind() == ::std::io::ErrorKind::NotFound {
|
if e.kind() == ::std::io::ErrorKind::NotFound {
|
||||||
|
@ -159,10 +160,8 @@ pub(crate) fn read_meta(dir: &Fd) -> Result<schema::DirMeta, Error> {
|
||||||
|
|
||||||
/// Write `dir`'s metadata, clobbering existing data.
|
/// Write `dir`'s metadata, clobbering existing data.
|
||||||
pub(crate) fn write_meta(dir: &Fd, meta: &schema::DirMeta) -> Result<(), Error> {
|
pub(crate) fn write_meta(dir: &Fd, meta: &schema::DirMeta) -> Result<(), Error> {
|
||||||
let (tmp_path, final_path) = unsafe {
|
let tmp_path = cstr!("meta.tmp");
|
||||||
(ffi::CStr::from_ptr("meta.tmp\0".as_ptr() as *const c_char),
|
let final_path = cstr!("meta");
|
||||||
ffi::CStr::from_ptr("meta\0".as_ptr() as *const c_char))
|
|
||||||
};
|
|
||||||
let mut f = unsafe { dir.openat(tmp_path.as_ptr(),
|
let mut f = unsafe { dir.openat(tmp_path.as_ptr(),
|
||||||
libc::O_CREAT | libc::O_TRUNC | libc::O_WRONLY, 0o600)? };
|
libc::O_CREAT | libc::O_TRUNC | libc::O_WRONLY, 0o600)? };
|
||||||
meta.write_to_writer(&mut f)?;
|
meta.write_to_writer(&mut f)?;
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::h264;
|
use crate::h264;
|
||||||
|
use cstr::*;
|
||||||
use failure::{Error, bail};
|
use failure::{Error, bail};
|
||||||
use ffmpeg;
|
use ffmpeg;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
@ -78,12 +79,6 @@ impl Ffmpeg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! c_str {
|
|
||||||
($s:expr) => { {
|
|
||||||
unsafe { CStr::from_ptr(concat!($s, "\0").as_ptr() as *const c_char) }
|
|
||||||
} }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Opener<FfmpegStream> for Ffmpeg {
|
impl Opener<FfmpegStream> for Ffmpeg {
|
||||||
fn open(&self, src: Source) -> Result<FfmpegStream, Error> {
|
fn open(&self, src: Source) -> Result<FfmpegStream, Error> {
|
||||||
use ffmpeg::InputFormatContext;
|
use ffmpeg::InputFormatContext;
|
||||||
|
@ -93,7 +88,7 @@ impl Opener<FfmpegStream> for Ffmpeg {
|
||||||
let mut open_options = ffmpeg::Dictionary::new();
|
let mut open_options = ffmpeg::Dictionary::new();
|
||||||
|
|
||||||
// Work around https://github.com/scottlamb/moonfire-nvr/issues/10
|
// Work around https://github.com/scottlamb/moonfire-nvr/issues/10
|
||||||
open_options.set(c_str!("advanced_editlist"), c_str!("false")).unwrap();
|
open_options.set(cstr!("advanced_editlist"), cstr!("false")).unwrap();
|
||||||
let url = format!("file:{}", filename);
|
let url = format!("file:{}", filename);
|
||||||
let i = InputFormatContext::open(&CString::new(url.clone()).unwrap(),
|
let i = InputFormatContext::open(&CString::new(url.clone()).unwrap(),
|
||||||
&mut open_options)?;
|
&mut open_options)?;
|
||||||
|
@ -105,14 +100,14 @@ impl Opener<FfmpegStream> for Ffmpeg {
|
||||||
}
|
}
|
||||||
Source::Rtsp{url, redacted_url} => {
|
Source::Rtsp{url, redacted_url} => {
|
||||||
let mut open_options = ffmpeg::Dictionary::new();
|
let mut open_options = ffmpeg::Dictionary::new();
|
||||||
open_options.set(c_str!("rtsp_transport"), c_str!("tcp")).unwrap();
|
open_options.set(cstr!("rtsp_transport"), cstr!("tcp")).unwrap();
|
||||||
open_options.set(c_str!("user-agent"), c_str!("moonfire-nvr")).unwrap();
|
open_options.set(cstr!("user-agent"), cstr!("moonfire-nvr")).unwrap();
|
||||||
// 10-second socket timeout, in microseconds.
|
// 10-second socket timeout, in microseconds.
|
||||||
open_options.set(c_str!("stimeout"), c_str!("10000000")).unwrap();
|
open_options.set(cstr!("stimeout"), cstr!("10000000")).unwrap();
|
||||||
|
|
||||||
// Moonfire NVR currently only supports video, so receiving audio is wasteful.
|
// Moonfire NVR currently only supports video, so receiving audio is wasteful.
|
||||||
// It also triggers <https://github.com/scottlamb/moonfire-nvr/issues/36>.
|
// It also triggers <https://github.com/scottlamb/moonfire-nvr/issues/36>.
|
||||||
open_options.set(c_str!("allowed_media_types"), c_str!("video")).unwrap();
|
open_options.set(cstr!("allowed_media_types"), cstr!("video")).unwrap();
|
||||||
|
|
||||||
let i = InputFormatContext::open(&CString::new(url).unwrap(), &mut open_options)?;
|
let i = InputFormatContext::open(&CString::new(url).unwrap(), &mut open_options)?;
|
||||||
if !open_options.empty() {
|
if !open_options.empty() {
|
||||||
|
|
Loading…
Reference in New Issue