Skip to content

Commit e72e4c4

Browse files
committed
fix: Files handling in sign_file
1 parent 2b61679 commit e72e4c4

File tree

2 files changed

+43
-8
lines changed

2 files changed

+43
-8
lines changed

src/c2pa/c2pa.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import warnings
77
from pathlib import Path
88
from typing import Optional, Union, Callable, Any, overload
9-
import time
9+
import io
1010
from .lib import dynamically_load_library
1111
import mimetypes
1212

@@ -1955,16 +1955,24 @@ def sign_file(self,
19551955
raise C2paError.NotSupported(
19561956
f"Could not determine MIME type for file: {source_path}")
19571957

1958-
# Open source and destination files
1959-
with open(source_path, 'rb') as source_file, open(dest_path, 'wb') as dest_file:
1958+
# Open source file and create BytesIO for destination
1959+
with open(source_path, 'rb') as source_file:
19601960
# Convert Python streams to Stream objects
19611961
source_stream = Stream(source_file)
1962-
dest_stream = Stream(dest_file)
1962+
dest_stream = Stream(io.BytesIO(bytearray()))
19631963

19641964
# Use the internal stream-base signing logic
1965-
return self._sign_internal(
1965+
# Sign the content to the BytesIO stream
1966+
result = self._sign_internal(
19661967
signer, mime_type, source_stream, dest_stream)
19671968

1969+
# Write the signed content from BytesIO to the destination file
1970+
dest_stream._file.seek(0) # Reset to beginning of stream
1971+
with open(dest_path, 'wb') as dest_file:
1972+
dest_file.write(dest_stream._file.getvalue())
1973+
1974+
return result
1975+
19681976

19691977
def format_embeddable(format: str, manifest_bytes: bytes) -> tuple[int, bytes]:
19701978
"""Convert a binary C2PA manifest into an embeddable version.

tests/test_unit_tests.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,33 @@ def test_builder_set_remote_url_no_embed(self):
812812
# Return back to default settings
813813
load_settings(r'{"verify": { "remote_manifest_fetch": true} }')
814814

815+
def test_sign_single_file(self):
816+
"""Test signing a file using the sign_file method."""
817+
# Create a temporary directory for the test
818+
temp_dir = tempfile.mkdtemp()
819+
try:
820+
# Create a temporary output file path
821+
output_path = os.path.join(temp_dir, "signed_output.jpg")
822+
823+
# Use the sign_file method
824+
builder = Builder(self.manifestDefinition)
825+
output = io.BytesIO(bytearray())
826+
827+
with open(self.testPath, "rb") as file:
828+
builder.sign(self.signer, "image/jpeg", file, output)
829+
output.seek(0)
830+
831+
# Read the signed file and verify the manifest
832+
reader = Reader("image/jpeg", output)
833+
json_data = reader.json()
834+
self.assertIn("Python Test", json_data)
835+
self.assertNotIn("validation_status", json_data)
836+
output.close()
837+
838+
finally:
839+
# Clean up the temporary directory
840+
shutil.rmtree(temp_dir)
841+
815842
def test_sign_file(self):
816843
"""Test signing a file using the sign_file method."""
817844
# Create a temporary directory for the test
@@ -823,9 +850,9 @@ def test_sign_file(self):
823850
# Use the sign_file method
824851
builder = Builder(self.manifestDefinition)
825852
manifest_bytes = builder.sign_file(
826-
source_path=self.testPath,
827-
dest_path=output_path,
828-
signer=self.signer
853+
self.testPath,
854+
output_path,
855+
self.signer
829856
)
830857

831858
# Verify the output file was created

0 commit comments

Comments
 (0)