Skip to content
Closed
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: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
cmake_minimum_required(VERSION 3.27)

# This is the current version of this C++ project
project(c2pa-c VERSION 0.25.1)
project(c2pa-c VERSION 0.23.16)

# Set the version of the c2pa_rs library used
set(C2PA_VERSION "0.89.0")
set(C2PA_VERSION "0.87.0")

set(CMAKE_POLICY_DEFAULT_CMP0135 NEW)
set(CMAKE_C_STANDARD 17)
Expand Down
1 change: 1 addition & 0 deletions compile_commands.json
96 changes: 0 additions & 96 deletions tests/builder.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3334,102 +3334,6 @@ TEST_F(BuilderTest, ExtractIngredientsFromArchiveToBuilder) {
EXPECT_EQ(merged_ingredients.size(), 3) << "Merged builder should have all 3 ingredients from both archives";
}

// An ingredient's validation state is carried over with the archive
TEST_F(BuilderTest, IngredientArchivePreservesIngredientValidationState) {
auto read_bytes = [](const fs::path& p) {
std::ifstream f(p, std::ios::binary);
return std::string((std::istreambuf_iterator<char>(f)), {});
};

// Force a dataHash mismatch in the ingredient
std::string corrupted = read_bytes(c2pa_test::get_fixture_path("C.jpg"));
ASSERT_GT(corrupted.size(), 4096u);
size_t flip_at = corrupted.size() - 1024;
corrupted[flip_at] = static_cast<char>(corrupted[flip_at] ^ 0xFF);

auto manifest = read_bytes(c2pa_test::get_fixture_path("training.json"));

// Archive the failing ingredient as-is
std::stringstream archive(std::ios::in | std::ios::out | std::ios::binary);
{
auto src_builder = c2pa::Builder(manifest);
std::stringstream corrupt_stream(corrupted,
std::ios::in | std::ios::out | std::ios::binary);
src_builder.add_ingredient(
R"({"title": "C.jpg", "relationship": "componentOf", "label": "ing-bad"})",
"image/jpeg", corrupt_stream);
src_builder.write_ingredient_archive("ing-bad", archive);
}

auto builder = c2pa::Builder(manifest);
archive.seekg(0);
ASSERT_NO_THROW(builder.add_ingredient_from_archive(archive));

auto signer = c2pa_test::create_test_signer();
auto output_path = get_temp_path("archive_mismatch_output.jpg");
ASSERT_NO_THROW(builder.sign(
c2pa_test::get_fixture_path("A.jpg"), output_path, signer));

// Verify ingredient state is still here
auto reader = c2pa::Reader(output_path);
auto parsed = json::parse(reader.json());
std::string active = parsed["active_manifest"];
auto ingredients = parsed["manifests"][active]["ingredients"];
ASSERT_EQ(ingredients.size(), 1u);

EXPECT_NE(ingredients[0].dump().find("assertion.dataHash.mismatch"), std::string::npos)
<< "ingredient state was lost during the ingredient-archive round-trip";
}

// An ingredient's validation state is carried over with the archive
TEST_F(BuilderTest, LegacyIngredientArchivePreservesIngredientValidationState) {
auto read_bytes = [](const fs::path& p) {
std::ifstream f(p, std::ios::binary);
return std::string((std::istreambuf_iterator<char>(f)), {});
};

// Force a dataHash mismatch in the ingredient
std::string corrupted = read_bytes(c2pa_test::get_fixture_path("C.jpg"));
ASSERT_GT(corrupted.size(), 4096u);
size_t flip_at = corrupted.size() - 1024;
corrupted[flip_at] = static_cast<char>(corrupted[flip_at] ^ 0xFF);

auto manifest = read_bytes(c2pa_test::get_fixture_path("training.json"));

// Archive a builder holding the single failing ingredient (legacy whole-builder archive)
std::stringstream archive(std::ios::in | std::ios::out | std::ios::binary);
{
auto src_builder = c2pa::Builder(manifest);
std::stringstream corrupt_stream(corrupted,
std::ios::in | std::ios::out | std::ios::binary);
src_builder.add_ingredient(
R"({"title": "C.jpg", "relationship": "componentOf", "label": "ing-bad"})",
"image/jpeg", corrupt_stream);
src_builder.to_archive(archive);
}

// Add the archive as an ingredient on a new builder, then sign
auto builder = c2pa::Builder(manifest);
archive.seekg(0);
ASSERT_NO_THROW(builder.add_ingredient(
R"({"title": "C.jpg", "relationship": "componentOf", "label": "ing-bad"})",
"application/c2pa", archive));

auto signer = c2pa_test::create_test_signer();
auto output_path = get_temp_path("legacy_archive_mismatch_output.jpg");
ASSERT_NO_THROW(builder.sign(c2pa_test::get_fixture_path("A.jpg"), output_path, signer));

// Verify ingredient state is still here
auto reader = c2pa::Reader(output_path);
auto parsed = json::parse(reader.json());
std::string active = parsed["active_manifest"];
auto ingredients = parsed["manifests"][active]["ingredients"];
ASSERT_EQ(ingredients.size(), 1u);

EXPECT_NE(ingredients[0].dump().find("assertion.dataHash.mismatch"), std::string::npos)
<< "ingredient state was lost during the ingredient-archive round-trip";
}

TEST_F(BuilderTest, ExtractIngredientsFromArchives) {
auto manifest = c2pa_test::read_text_file(c2pa_test::get_fixture_path("training.json"));

Expand Down
Loading