Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

(MINOR) Added ResourceNotFound error #244

Merged
merged 4 commits into from
May 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions sdk/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use thiserror::Error;

/// `Error` enumerates errors returned by most C2PA toolkit operations.
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum Error {
// --- c2pa errors ---
/// Could not find a claim with this label.
Expand Down Expand Up @@ -198,6 +199,9 @@ pub enum Error {
#[error("file not found: {0}")]
FileNotFound(String),

#[error("resource not found: {0}")]
ResourceNotFound(String),

#[error("XMP read error")]
XmpReadError,

Expand Down
18 changes: 11 additions & 7 deletions sdk/src/ingredient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -855,8 +855,8 @@ impl Ingredient {

// add the ingredient manifest_data to the claim
// this is how any existing claims are added to the new store
let c2pa_manifest = match self.manifest_data() {
Some(buffer) => {
let c2pa_manifest = match self.manifest_data_ref() {
Some(resource_ref) => {
let manifest_label = self
.active_manifest
.clone()
Expand All @@ -873,9 +873,12 @@ impl Ingredient {
false => None,
};

// get the c2pa manifest bytes
let data = self.resources.get(&resource_ref.identifier)?;

// have Store check and load ingredients and add them to a claim
let ingredient_store =
Store::load_ingredient_to_claim(claim, &manifest_label, &buffer, redactions)?;
Store::load_ingredient_to_claim(claim, &manifest_label, &data, redactions)?;

// get the ingredient map loaded in previous
match claim.claim_ingredient(&manifest_label) {
Expand Down Expand Up @@ -931,10 +934,11 @@ impl Ingredient {

// if the ingredient defines a thumbnail, add it to the claim
// otherwise use the parent claim thumbnail if available
if let Some((format, data)) = self.thumbnail() {
if let Some(thumb_ref) = self.thumbnail_ref() {
let data = self.thumbnail_bytes()?;
let hash_url = claim.add_assertion(&Thumbnail::new(
&labels::add_thumbnail_format(labels::INGREDIENT_THUMBNAIL, format),
data.to_vec(),
&labels::add_thumbnail_format(labels::INGREDIENT_THUMBNAIL, &thumb_ref.format),
data.into_owned(),
))?;
thumbnail = Some(hash_url);
}
Expand Down Expand Up @@ -1371,7 +1375,7 @@ mod tests_file_io {
println!("ingredient = {ingredient}");
assert_eq!(ingredient.validation_status(), None);

// verify we can't set a references that don't exist
// verify we can't set references that don't exist
assert!(ingredient
.set_thumbnail_ref(ResourceRef::new("Foo", "bar"))
.is_err());
Expand Down
35 changes: 25 additions & 10 deletions sdk/src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
// specific language governing permissions and limitations under
// each license.

#[cfg(feature = "file_io")]
use std::path::Path;
use std::{borrow::Cow, collections::HashMap, io::Cursor};
#[cfg(feature = "file_io")]
use std::{fs::create_dir_all, path::Path};

use log::{debug, error, warn};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
Expand Down Expand Up @@ -483,7 +483,7 @@ impl Manifest {
/// Ingredients resources will also be relative to this path
#[cfg(feature = "file_io")]
pub fn with_base_path<P: AsRef<Path>>(&mut self, base_path: P) -> Result<&Self> {
std::fs::create_dir_all(&base_path)?;
create_dir_all(&base_path)?;
self.resources.set_base_path(base_path.as_ref());
for i in 0..self.ingredients.len() {
// todo: create different subpath for each ingredient?
Expand Down Expand Up @@ -626,7 +626,7 @@ impl Manifest {
}

// if a thumbnail is not already defined, create one here
if self.thumbnail().is_none() {
if self.thumbnail_ref().is_none() {
#[cfg(feature = "add_thumbnails")]
if let Ok((format, image)) = crate::utils::thumbnail::make_thumbnail(path.as_ref()) {
// Do not write this as a file when reading from files
Expand Down Expand Up @@ -669,10 +669,12 @@ impl Manifest {
}
claim.format = self.format().to_owned();
claim.instance_id = self.instance_id().to_owned();
if let Some((format, data)) = self.thumbnail() {

if let Some(thumb_ref) = self.thumbnail_ref() {
let data = self.resources.get(&thumb_ref.identifier)?;
claim.add_assertion(&Thumbnail::new(
&labels::add_thumbnail_format(labels::CLAIM_THUMBNAIL, format),
data.to_vec(),
&labels::add_thumbnail_format(labels::CLAIM_THUMBNAIL, &thumb_ref.format),
data.into_owned(),
))?;
}

Expand Down Expand Up @@ -804,6 +806,10 @@ impl Manifest {
}
// we need to copy the source to target before setting the asset info
if !dest_path.as_ref().exists() {
// ensure the path to the file exists
if let Some(output_dir) = dest_path.as_ref().parent() {
create_dir_all(output_dir)?;
}
std::fs::copy(&source_path, &dest_path)?;
copied = true;
}
Expand Down Expand Up @@ -1769,10 +1775,14 @@ pub(crate) mod tests {
#[test]
#[cfg(feature = "file_io")]
fn test_create_file_based_ingredient() {
let mut folder = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
folder.push("tests/fixtures");
let mut fixtures = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
fixtures.push("tests/fixtures");

let temp_dir = tempdir().expect("temp dir");
let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG);

let mut manifest = Manifest::new("claim_generator");
manifest.resources.set_base_path(folder);
manifest.with_base_path(fixtures).expect("with_base");
// verify we can't set a references that don't exist
assert!(manifest
.set_thumbnail_ref(ResourceRef::new("image/jpg", "foo"))
Expand All @@ -1783,5 +1793,10 @@ pub(crate) mod tests {
.set_thumbnail_ref(ResourceRef::new("image/jpg", "C.jpg"))
.is_ok());
assert!(manifest.thumbnail_ref().is_some());

let signer = temp_signer();
manifest
.embed(&output, &output, signer.as_ref())
.expect("embed");
}
}
7 changes: 5 additions & 2 deletions sdk/src/resource_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,13 @@ impl ResourceStore {
Some(base) => {
// read the file, save in Map and then return a reference
let path = base.join(id);
let value = std::fs::read(path)?;
let value = std::fs::read(path).map_err(|_| {
let path = base.join(id).to_string_lossy().into_owned();
Error::ResourceNotFound(path)
})?;
return Ok(Cow::Owned(value));
}
None => return Err(Error::NotFound),
None => return Err(Error::ResourceNotFound(id.to_string())),
}
}
self.resources
Expand Down