Skip to content

Commit

Permalink
Introduce new error type XmpErrorType::NulInRustString (#68)
Browse files Browse the repository at this point in the history
Use this to remove some `.unwrap()` calls in `XmpMeta`.
  • Loading branch information
scouten-adobe authored Jul 17, 2022
1 parent f965a11 commit 5e7bc7a
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 11 deletions.
33 changes: 33 additions & 0 deletions src/tests/xmp_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,23 @@ mod set_property {
assert_eq!(err.error_type, XmpErrorType::BadXPath);
assert_eq!(err.debug_message, "Empty property name");
}

#[test]
fn error_nul_in_name() {
let mut m = XmpMeta::from_file(fixture_path("Purple Square.psd")).unwrap();

XmpMeta::register_namespace("http://purl.org/dc/terms/", "dcterms").unwrap();

let err = m
.set_property("http://purl.org/dc/terms/", "x\0x", "blah")
.unwrap_err();

assert_eq!(err.error_type, XmpErrorType::NulInRustString);
assert_eq!(
err.debug_message,
"Unable to convert to C string because a NUL byte was found"
);
}
}

mod does_property_exist {
Expand Down Expand Up @@ -200,4 +217,20 @@ mod set_property_date {
assert_eq!(err.error_type, XmpErrorType::BadSchema);
assert_eq!(err.debug_message, "Empty schema namespace URI");
}

#[test]
fn error_nul_in_name() {
let mut m = XmpMeta::from_file(fixture_path("Purple Square.psd")).unwrap();
let updated_time = XmpDateTime::current().unwrap();

let err = m
.set_property_date("x\0x", "MetadataDate", &updated_time)
.unwrap_err();

assert_eq!(err.error_type, XmpErrorType::NulInRustString);
assert_eq!(
err.debug_message,
"Unable to convert to C string because a NUL byte was found"
);
}
}
29 changes: 23 additions & 6 deletions src/xmp_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
// specific language governing permissions and limitations under
// each license.

use std::{ffi::CStr, fmt};

use num_enum::FromPrimitive;
use thiserror::Error;

use crate::ffi::CXmpError;
use {
crate::ffi::CXmpError,
num_enum::FromPrimitive,
std::{
ffi::{CStr, NulError},
fmt,
},
thiserror::Error,
};

/// Describes error conditions returned by most XMP Toolkit operations.
#[derive(Debug)]
Expand Down Expand Up @@ -51,6 +54,15 @@ impl XmpError {
}
}

impl From<NulError> for XmpError {
fn from(_: NulError) -> Self {
XmpError {
error_type: XmpErrorType::NulInRustString,
debug_message: "Unable to convert to C string because a NUL byte was found".to_owned(),
}
}
}

impl fmt::Display for XmpError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
if self.debug_message.is_empty() {
Expand Down Expand Up @@ -263,6 +275,11 @@ pub enum XmpErrorType {
/// PNG format error.
#[error("PNG format error")]
BadPng = 213,

// --- Rust-specific errors ---
/// Can not convert from Rust string to C string because a NUL byte was found.
#[error("Unable to convert to C string because a NUL byte was found")]
NulInRustString = -432,
}

/// A specialized `Result` type for XMP Toolkit operations.
Expand Down
10 changes: 5 additions & 5 deletions src/xmp_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ impl XmpMeta {
prop_name: &str,
prop_value: &str,
) -> XmpResult<()> {
let c_ns = CString::new(schema_ns).unwrap();
let c_name = CString::new(prop_name).unwrap();
let c_value = CString::new(prop_value).unwrap();
let c_ns = CString::new(schema_ns)?;
let c_name = CString::new(prop_name)?;
let c_value = CString::new(prop_value)?;
let mut err = ffi::CXmpError::default();

unsafe {
Expand Down Expand Up @@ -196,8 +196,8 @@ impl XmpMeta {
prop_name: &str,
prop_value: &XmpDateTime,
) -> XmpResult<()> {
let c_ns = CString::new(schema_ns).unwrap();
let c_name = CString::new(prop_name).unwrap();
let c_ns = CString::new(schema_ns)?;
let c_name = CString::new(prop_name)?;
let mut err = ffi::CXmpError::default();

unsafe {
Expand Down

0 comments on commit 5e7bc7a

Please sign in to comment.