summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2023-06-27 00:11:43 +0200
committerCarl Hetherington <cth@carlh.net>2023-06-29 01:25:40 +0200
commite702623781c8d5853b79a29ca8c5f495d0ade3d1 (patch)
tree50240036d3cf18d87c9582d71e5fd3ee2d29e8e5 /src
parentd305bb807a686fd7850257a724f46a77977fe491 (diff)
When reading a DCP set up asset hashes from the CPL/PKL, not by digesting the actual asset.
Previously when reading a DCP we would recalculate asset hashes. This meant that corrupted DCPs could be loaded in and their hashes re-written (if nobody checked the new hashes against the ones in the PKL/CPL). It seems better to take the hashes from the metadata. Then if the assets are corrupted and the DCP is re-written the PKL/CPL hashes will be preserved, showing rather than hiding the corruption.
Diffstat (limited to 'src')
-rw-r--r--src/dcp.cc42
-rw-r--r--src/verify.cc6
2 files changed, 48 insertions, 0 deletions
diff --git a/src/dcp.cc b/src/dcp.cc
index 0d0dc690..3b267090 100644
--- a/src/dcp.cc
+++ b/src/dcp.cc
@@ -270,6 +270,48 @@ DCP::read (vector<dcp::VerificationNote>* notes, bool ignore_incorrect_picture_m
}
}
+ /* Set hashes for assets where we have an idea of what the hash should be in either a CPL or PKL.
+ * This means that when the hash is later read from these objects the result will be the one that
+ * it should be, rather the one that it currently is. This should prevent errors being concealed
+ * when an asset is corrupted - the hash from the CPL/PKL will disagree with the actual hash of the
+ * file, revealing the problem.
+ */
+
+ auto hash_from_pkl = [this](string id) -> optional<string> {
+ for (auto pkl: _pkls) {
+ if (auto pkl_hash = pkl->hash(id)) {
+ return pkl_hash;
+ }
+ }
+
+ return {};
+ };
+
+ auto hash_from_cpl_or_pkl = [this, &hash_from_pkl](string id) -> optional<string> {
+ for (auto cpl: cpls()) {
+ for (auto reel_file_asset: cpl->reel_file_assets()) {
+ if (reel_file_asset->asset_ref().id() == id && reel_file_asset->hash()) {
+ return reel_file_asset->hash();
+ }
+ }
+ }
+
+ return hash_from_pkl(id);
+ };
+
+ for (auto asset: other_assets) {
+ if (auto hash = hash_from_cpl_or_pkl(asset->id())) {
+ asset->set_hash(*hash);
+ }
+ }
+
+ for (auto cpl: cpls()) {
+ if (auto hash = hash_from_pkl(cpl->id())) {
+ cpl->set_hash(*hash);
+ }
+ }
+
+ /* Resolve references */
resolve_refs (other_assets);
/* While we've got the ASSETMAP lets look and see if this DCP refers to things that are not in its ASSETMAP */
diff --git a/src/verify.cc b/src/verify.cc
index 394326fe..8f318af9 100644
--- a/src/verify.cc
+++ b/src/verify.cc
@@ -386,6 +386,12 @@ enum class VerifyAssetResult {
static VerifyAssetResult
verify_asset (shared_ptr<const DCP> dcp, shared_ptr<const ReelFileAsset> reel_file_asset, function<void (float)> progress)
{
+ /* When reading the DCP the hash will have been set to the one from the PKL/CPL.
+ * We want to calculate the hash of the actual file contents here, so that we
+ * can check it. unset_hash() means that this calculation will happen on the
+ * call to hash().
+ */
+ reel_file_asset->asset_ref()->unset_hash();
auto const actual_hash = reel_file_asset->asset_ref()->hash(progress);
auto pkls = dcp->pkls();