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:
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)
+}