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
18 changes: 17 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Checkout c2pa-rs (0.92.1)
uses: actions/checkout@v4
with:
repository: contentauth/c2pa-rs
ref: c2pa-v0.92.1
path: c2pa-rs

- name: Configure c2pa-rs release source build
shell: bash
run: |
git -C c2pa-rs log -1 --format='c2pa-rs checkout: %H %s'
cargo --version
rustc --version
echo "C2PA_BUILD_FROM_SOURCE=ON" >> "$GITHUB_ENV"
echo "C2PA_RS_PATH=${GITHUB_WORKSPACE//\\//}/c2pa-rs" >> "$GITHUB_ENV"

- name: Check cmake
run: cmake --version

Expand All @@ -82,7 +98,7 @@ jobs:
which make
make --version

- name: Build and test against c2pa-rs 0.92.0 release
- name: Build and test against c2pa-rs 0.92.1 release
run: make test

- name: Run tests (debug build, with sanitizers)
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ cmake_minimum_required(VERSION 3.27)
project(c2pa-c VERSION 0.27.0)

# Set the version of the c2pa_rs library used
set(C2PA_VERSION "0.92.0")
set(C2PA_VERSION "0.92.1")

set(CMAKE_POLICY_DEFAULT_CMP0135 NEW)
set(CMAKE_C_STANDARD 17)
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ BUILD_DIR = build
DEBUG_BUILD_DIR = build/debug
RELEASE_BUILD_DIR = build/release

# Use published c2pa-rs binaries by default; source builds remain opt-in.
C2PA_BUILD_FROM_SOURCE ?= OFF

# CMake options (can be overridden via environment)
CMAKE_OPTS :=
ifdef C2PA_BUILD_FROM_SOURCE
Expand Down
2 changes: 2 additions & 0 deletions include/c2pa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,8 @@ namespace c2pa
/// @details The callback is invoked synchronously whenever the SDK needs to
/// make an HTTP request (remote manifest fetch, OCSP, timestamp, etc.).
/// The callback receives a C2paHttpRequest and must fill in a C2paHttpResponse.
/// The SDK cannot interrupt the callback; configure appropriate timeouts
/// on its HTTP client.
/// The response body must be allocated with malloc(); the underlying native library will call free().
/// @param user_data Opaque user pointer passed to every callback invocation (may be nullptr).
/// @param callback Function pointer matching C2paHttpResolverCallback.
Expand Down
28 changes: 14 additions & 14 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,30 +88,30 @@ if(C2PA_BUILD_FROM_SOURCE)
find_program(CARGO_EXECUTABLE cargo PATHS "$ENV{HOME}/.cargo/bin" REQUIRED)
message(STATUS "Found cargo at: ${CARGO_EXECUTABLE}")

set(C2PA_RUST_ARTIFACTS "${C2PA_LIB_NAME}" "c2pa.h")
if(WIN32)
list(APPEND C2PA_RUST_ARTIFACTS "${C2PA_IMPLIB_NAME}")
endif()
set(C2PA_RUST_SOURCES ${C2PA_RUST_ARTIFACTS})
list(TRANSFORM C2PA_RUST_SOURCES PREPEND "${C2PA_RS_PATH}/target/release/")
set(C2PA_RUST_OUTPUTS ${C2PA_RUST_ARTIFACTS})
list(TRANSFORM C2PA_RUST_OUTPUTS PREPEND "${C2PA_RUST_BUILD_DIR}/")

# Build the Rust c2pa_c_ffi library
add_custom_command(
OUTPUT "${C2PA_RUST_BUILD_DIR}/${C2PA_LIB_NAME}"
OUTPUT ${C2PA_RUST_OUTPUTS}
COMMAND ${CARGO_EXECUTABLE} build --release --package c2pa-c-ffi --no-default-features --features "rust_native_crypto, file_io, http, add_thumbnails"
COMMAND ${CMAKE_COMMAND} -E copy
"${C2PA_RS_PATH}/target/release/${C2PA_LIB_NAME}"
"${C2PA_RUST_BUILD_DIR}/${C2PA_LIB_NAME}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${C2PA_RUST_SOURCES}
"${C2PA_RUST_BUILD_DIR}"
WORKING_DIRECTORY "${C2PA_RS_PATH}"
COMMENT "Building c2pa_c from source using Cargo"
VERBATIM
)

# Create a custom target that depends on the library
add_custom_target(build_c2pa_c ALL
DEPENDS "${C2PA_RUST_BUILD_DIR}/${C2PA_LIB_NAME}"
)

# Copy the generated c2pa.h header
add_custom_command(
TARGET build_c2pa_c POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${C2PA_RS_PATH}/target/release/c2pa.h"
"${C2PA_RUST_BUILD_DIR}/c2pa.h"
COMMENT "Copying c2pa.h header"
DEPENDS ${C2PA_RUST_OUTPUTS}
)

set(C2PA_C_LIB "${C2PA_RUST_BUILD_DIR}/${C2PA_LIB_NAME}")
Expand Down
37 changes: 37 additions & 0 deletions tests/context.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -874,3 +874,40 @@ TEST_F(ContextTest, ContextMoveAssignWithCallbackPreservesInvocation) {
EXPECT_EQ(lhs.load(), 0);
EXPECT_GT(rhs.load(), 0);
}

#if 0 // TODO: Re-enable when C2paHttpRequest.timeout_ms is published (absent in 0.92.1).
static int capture_timeout(void* user_data, const C2paHttpRequest* request, C2paHttpResponse* response)
{
static_cast<std::atomic<uint64_t>*>(user_data)->store(request->timeout_ms);
response->status = 200;
response->body = nullptr;
response->body_len = 0;
return 0;
}

TEST(Context, HttpResolverReceivesRemoteManifestTimeout)
{
for (const auto& [settings_json, expected] : {
std::pair<const char*, uint64_t>{"{}", 10000},
std::pair<const char*, uint64_t>{
R"({"core":{"http_request_timeout_in_ms":2500}})", 2500},
}) {
std::atomic<uint64_t> seen{0};
c2pa::Context context = c2pa::Context::ContextBuilder()
.with_json(settings_json)
.with_http_resolver(&seen, capture_timeout)
.create_context();

std::ifstream asset(fixture_path("cloud.jpg"), std::ios::binary);
ASSERT_TRUE(asset.is_open());
try {
c2pa::Reader reader(context, "image/jpeg", asset);
} catch (const c2pa::C2paException&) {
// The empty callback response is not a manifest; only the request matters here.
}

EXPECT_LE(seen.load(), expected);
EXPECT_GE(seen.load(), expected - 100);
}
}
#endif