c2pa-rs

A fork of https://github.com/contentauth/c2pa-rs/
git clone git://archive.git.mtrnord.blog/mtrnords-photography-manager/c2pa-rs.git
Log | Files | Refs | README

commit 24cb20d7dd3ea4ce65b968c0bb3782afe8254401
parent f16190680c7acb4a3d2cbeefcf95f263e28b54cf
Author: Gavin  Peacock <gpeacock@adobe.com>
Date:   Mon,  4 Dec 2023 10:02:20 -0800

CAI-5041 Clear Windows temp attribute (#352)

* CAI-5041 Clear Windows temp attribute
NamedTempFile sets this attribute, so clear it before renaming

* Remove rsa dependency

* Restore rsa because we need it for wasm

* Restore Rsa

* Adds RUSTSEC-2023-0071 to deny.toml
remove this when a fix for the RSA issue is available
https://jira.corp.adobe.com/browse/CAI-5104
Diffstat:
Mdeny.toml | 1+
Msdk/src/asset_handlers/bmff_io.rs | 14++++----------
Msdk/src/asset_handlers/jpeg_io.rs | 12+++++-------
Msdk/src/asset_handlers/mp3_io.rs | 10++++------
Msdk/src/asset_handlers/png_io.rs | 10++++------
Msdk/src/asset_handlers/riff_io.rs | 10++++------
Msdk/src/asset_handlers/svg_io.rs | 11+++--------
Msdk/src/asset_handlers/tiff_io.rs | 12+++---------
Msdk/src/asset_io.rs | 18++++++++++++++++++
9 files changed, 46 insertions(+), 52 deletions(-)

diff --git a/deny.toml b/deny.toml @@ -23,6 +23,7 @@ ignore = [ "RUSTSEC-2021-0127", # serde_cbor "RUSTSEC-2021-0146", # twoway (see https://github.com/contentauth/c2pa-rs/issues/234) "RUSTSEC-2022-0081", # json (see https://github.com/contentauth/c2pa-rs/issues/318) + "RUSTSEC-2023-0071", # rsa Marvin Attack: (https://jira.corp.adobe.com/browse/CAI-5104) ] # Deny multiple versions unless explicitly skipped. diff --git a/sdk/src/asset_handlers/bmff_io.rs b/sdk/src/asset_handlers/bmff_io.rs @@ -28,8 +28,8 @@ use tempfile::Builder; use crate::{ assertions::{BmffMerkleMap, ExclusionsMap}, asset_io::{ - AssetIO, AssetPatch, CAIRead, CAIReadWrite, CAIReader, HashObjectPositions, RemoteRefEmbed, - RemoteRefEmbedType, + rename_or_copy, AssetIO, AssetPatch, CAIRead, CAIReadWrite, CAIReader, HashObjectPositions, + RemoteRefEmbed, RemoteRefEmbedType, }, error::{Error, Result}, utils::hash_utils::{vec_compare, HashRange}, @@ -1372,10 +1372,7 @@ impl AssetIO for BmffIO { )?; // copy temp file to asset - std::fs::rename(temp_file.path(), asset_path) - // if rename fails, try to copy in case we are on different volumes - .or_else(|_| std::fs::copy(temp_file.path(), asset_path).and(Ok(()))) - .map_err(Error::IoError) + rename_or_copy(temp_file, asset_path) } fn get_object_locations( @@ -1503,10 +1500,7 @@ impl AssetIO for BmffIO { } // copy temp file to asset - std::fs::rename(temp_file.path(), asset_path) - // if rename fails, try to copy in case we are on different volumes - .or_else(|_| std::fs::copy(temp_file.path(), asset_path).and(Ok(()))) - .map_err(Error::IoError) + rename_or_copy(temp_file, asset_path) } fn new(asset_type: &str) -> Self diff --git a/sdk/src/asset_handlers/jpeg_io.rs b/sdk/src/asset_handlers/jpeg_io.rs @@ -33,8 +33,9 @@ use tempfile::Builder; use crate::{ assertions::{BoxMap, C2PA_BOXHASH}, asset_io::{ - AssetBoxHash, AssetIO, CAIRead, CAIReadWrite, CAIReader, CAIWriter, ComposedManifestRef, - HashBlockObjectType, HashObjectPositions, RemoteRefEmbed, RemoteRefEmbedType, + rename_or_copy, AssetBoxHash, AssetIO, CAIRead, CAIReadWrite, CAIReader, CAIWriter, + ComposedManifestRef, HashBlockObjectType, HashObjectPositions, RemoteRefEmbed, + RemoteRefEmbedType, }, error::{Error, Result}, }; @@ -188,7 +189,7 @@ impl CAIReader for JpegIO { let app11 = jpeg.segments_by_marker(markers::APP11); let mut cai_en: Vec<u8> = Vec::new(); let mut cai_seg_cnt: u32 = 0; - for (_i, segment) in app11.enumerate() { + for segment in app11 { let raw_bytes = segment.contents(); if raw_bytes.len() > 16 { // we need at least 16 bytes in each segment for CAI @@ -475,10 +476,7 @@ impl AssetIO for JpegIO { self.write_cai(&mut input_stream, &mut temp_file, store_bytes)?; // copy temp file to asset - std::fs::rename(temp_file.path(), asset_path) - // if rename fails, try to copy in case we are on different volumes - .or_else(|_| std::fs::copy(temp_file.path(), asset_path).and(Ok(()))) - .map_err(Error::IoError) + rename_or_copy(temp_file, asset_path) } fn get_object_locations(&self, asset_path: &Path) -> Result<Vec<HashObjectPositions>> { diff --git a/sdk/src/asset_handlers/mp3_io.rs b/sdk/src/asset_handlers/mp3_io.rs @@ -25,8 +25,9 @@ use twoway::find_bytes; use crate::{ asset_io::{ - AssetIO, AssetPatch, CAIRead, CAIReadWrapper, CAIReadWrite, CAIReadWriteWrapper, CAIReader, - CAIWriter, HashBlockObjectType, HashObjectPositions, RemoteRefEmbed, + rename_or_copy, AssetIO, AssetPatch, CAIRead, CAIReadWrapper, CAIReadWrite, + CAIReadWriteWrapper, CAIReader, CAIWriter, HashBlockObjectType, HashObjectPositions, + RemoteRefEmbed, }, error::{Error, Result}, }; @@ -212,10 +213,7 @@ impl AssetIO for Mp3IO { self.write_cai(&mut input_stream, &mut temp_file, store_bytes)?; // copy temp file to asset - std::fs::rename(temp_file.path(), asset_path) - // if rename fails, try to copy in case we are on different volumes - .or_else(|_| std::fs::copy(temp_file.path(), asset_path).and(Ok(()))) - .map_err(Error::IoError) + rename_or_copy(temp_file, asset_path) } fn get_object_locations( diff --git a/sdk/src/asset_handlers/png_io.rs b/sdk/src/asset_handlers/png_io.rs @@ -25,8 +25,9 @@ use tempfile::Builder; use crate::{ assertions::{BoxMap, C2PA_BOXHASH}, asset_io::{ - AssetBoxHash, AssetIO, CAIRead, CAIReadWrite, CAIReader, CAIWriter, ComposedManifestRef, - HashBlockObjectType, HashObjectPositions, RemoteRefEmbed, RemoteRefEmbedType, + rename_or_copy, AssetBoxHash, AssetIO, CAIRead, CAIReadWrite, CAIReader, CAIWriter, + ComposedManifestRef, HashBlockObjectType, HashObjectPositions, RemoteRefEmbed, + RemoteRefEmbedType, }, error::{Error, Result}, }; @@ -486,10 +487,7 @@ impl AssetIO for PngIO { self.write_cai(&mut stream, &mut temp_file, store_bytes)?; // copy temp file to asset - std::fs::rename(temp_file.path(), asset_path) - // if rename fails, try to copy in case we are on different volumes - .or_else(|_| std::fs::copy(temp_file.path(), asset_path).and(Ok(()))) - .map_err(Error::IoError) + rename_or_copy(temp_file, asset_path) } fn get_object_locations( diff --git a/sdk/src/asset_handlers/riff_io.rs b/sdk/src/asset_handlers/riff_io.rs @@ -24,8 +24,9 @@ use tempfile::Builder; use crate::{ asset_io::{ - AssetIO, AssetPatch, CAIRead, CAIReadWrapper, CAIReadWrite, CAIReadWriteWrapper, CAIReader, - CAIWriter, HashBlockObjectType, HashObjectPositions, RemoteRefEmbed, RemoteRefEmbedType, + rename_or_copy, AssetIO, AssetPatch, CAIRead, CAIReadWrapper, CAIReadWrite, + CAIReadWriteWrapper, CAIReader, CAIWriter, HashBlockObjectType, HashObjectPositions, + RemoteRefEmbed, RemoteRefEmbedType, }, error::{Error, Result}, utils::xmp_inmemory_utils::{add_provenance, MIN_XMP}, @@ -368,10 +369,7 @@ impl AssetIO for RiffIO { self.write_cai(&mut input_stream, &mut temp_file, store_bytes)?; // copy temp file to asset - std::fs::rename(temp_file.path(), asset_path) - // if rename fails, try to copy in case we are on different volumes - .or_else(|_| std::fs::copy(temp_file.path(), asset_path).and(Ok(()))) - .map_err(Error::IoError) + rename_or_copy(temp_file, asset_path) } fn get_object_locations( diff --git a/sdk/src/asset_handlers/svg_io.rs b/sdk/src/asset_handlers/svg_io.rs @@ -26,6 +26,7 @@ use tempfile::Builder; use crate::{ asset_io::{ + rename_or_copy, AssetIO, AssetPatch, CAIRead, @@ -123,10 +124,7 @@ impl AssetIO for SvgIO { self.write_cai(&mut input_stream, &mut temp_file, store_bytes)?; // copy temp file to asset - std::fs::rename(temp_file.path(), asset_path) - // if rename fails, try to copy in case we are on different volumes - .or_else(|_| std::fs::copy(temp_file.path(), asset_path).and(Ok(()))) - .map_err(Error::IoError) + rename_or_copy(temp_file, asset_path) } fn get_object_locations( @@ -150,10 +148,7 @@ impl AssetIO for SvgIO { self.remove_cai_store_from_stream(&mut input_file, &mut temp_file)?; // copy temp file to asset - std::fs::rename(temp_file.path(), asset_path) - // if rename fails, try to copy in case we are on different volumes - .or_else(|_| std::fs::copy(temp_file.path(), asset_path).and(Ok(()))) - .map_err(Error::IoError) + rename_or_copy(temp_file, asset_path) } fn remote_ref_writer_ref(&self) -> Option<&dyn RemoteRefEmbed> { diff --git a/sdk/src/asset_handlers/tiff_io.rs b/sdk/src/asset_handlers/tiff_io.rs @@ -26,7 +26,7 @@ use tempfile::Builder; use crate::{ asset_io::{ - AssetIO, AssetPatch, CAIRead, CAIReadWrite, CAIReader, ComposedManifestRef, + rename_or_copy, AssetIO, AssetPatch, CAIRead, CAIReadWrite, CAIReader, ComposedManifestRef, HashBlockObjectType, HashObjectPositions, RemoteRefEmbed, RemoteRefEmbedType, }, error::{Error, Result}, @@ -1399,10 +1399,7 @@ impl AssetIO for TiffIO { tiff_clone_with_tags(&mut temp_file, &mut reader, vec![entry])?; // copy temp file to asset - std::fs::rename(temp_file.path(), asset_path) - // if rename fails, try to copy in case we are on different volumes - .or_else(|_| std::fs::copy(temp_file.path(), asset_path).and(Ok(()))) - .map_err(Error::IoError) + rename_or_copy(temp_file, asset_path) } fn get_object_locations( @@ -1458,10 +1455,7 @@ impl AssetIO for TiffIO { tc.clone_tiff(&mut idfs, page_0, &mut asset_reader)?; // copy temp file to asset - std::fs::rename(temp_file.path(), asset_path) - // if rename fails, try to copy in case we are on different volumes - .or_else(|_| std::fs::copy(temp_file.path(), asset_path).and(Ok(()))) - .map_err(Error::IoError) + rename_or_copy(temp_file, asset_path) } None => Ok(()), } diff --git a/sdk/src/asset_io.rs b/sdk/src/asset_io.rs @@ -257,3 +257,21 @@ pub trait ComposedManifestRef { // Return entire CAI block as Vec<u8> fn compose_manifest(&self, manifest_data: &[u8], format: &str) -> Result<Vec<u8>>; } + +/// Utility funtion to rename or copy a temp file to a permanent location. +/// +/// If the rename is not possible, due to cross volume references & etc, it will copy instead. +pub fn rename_or_copy<P>(temp_file: NamedTempFile, asset_path: P) -> Result<()> +where + P: AsRef<Path>, +{ + // clear temp flag for Windows + let (_, path) = temp_file + .keep() + .map_err(|e| crate::Error::OtherError(Box::new(e)))?; + + std::fs::rename(&path, asset_path.as_ref()) + // if rename fails, try to copy in case we are on different volumes + .or_else(|_| std::fs::copy(&path, asset_path).and(Ok(()))) + .map_err(crate::Error::IoError) +}