Skip to content

Commit a60d376

Browse files
committed
fix: Plenty of debug logs
1 parent 07729ac commit a60d376

File tree

2 files changed

+216
-15
lines changed

2 files changed

+216
-15
lines changed

src/c2pa/c2pa.py

Lines changed: 210 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,33 @@
99
import time
1010
from .lib import dynamically_load_library
1111
import mimetypes
12+
import logging
13+
14+
# Force output to stderr immediately
15+
sys.stderr.write("## c2pa module loading - logging setup starting\n")
16+
sys.stderr.flush()
17+
18+
# Configure logging for the c2pa module
19+
logging.basicConfig(
20+
level=logging.DEBUG,
21+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
22+
force=True # Force reconfiguration even if already configured
23+
)
24+
25+
# Get the logger for this module
26+
logger = logging.getLogger(__name__)
27+
logger.setLevel(logging.DEBUG)
28+
29+
# Ensure the logger has a handler
30+
if not logger.handlers:
31+
handler = logging.StreamHandler(sys.stderr) # Force to stderr
32+
handler.setLevel(logging.DEBUG)
33+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
34+
handler.setFormatter(formatter)
35+
logger.addHandler(handler)
36+
37+
sys.stderr.write("## c2pa module loading - logging setup complete\n")
38+
sys.stderr.flush()
1239

1340
# Define required function names
1441
_REQUIRED_FUNCTIONS = [
@@ -1308,6 +1335,13 @@ def from_callback(
13081335
C2paError: If there was an error creating the signer
13091336
C2paError.Encoding: If the certificate data or TSA URL contains invalid UTF-8 characters
13101337
"""
1338+
import logging
1339+
logger = logging.getLogger(__name__)
1340+
1341+
sys.stderr.write("## Signer.from_callback called\n")
1342+
sys.stderr.flush()
1343+
logger.info("Signer.from_callback called")
1344+
13111345
# Validate inputs before creating
13121346
if not certs:
13131347
raise C2paError(
@@ -1317,17 +1351,74 @@ def from_callback(
13171351
raise C2paError(
13181352
cls._error_messages['invalid_tsa'].format("Invalid TSA URL format"))
13191353

1354+
sys.stderr.write("## Creating wrapped_callback\n")
1355+
sys.stderr.flush()
1356+
logger.info("Creating wrapped_callback")
1357+
13201358
# Create a wrapper callback that handles errors and memory management
1321-
def wrapped_callback(data: bytes) -> bytes:
1359+
def wrapped_callback(context, data_ptr, data_len, signed_bytes_ptr, signed_len):
1360+
logger = logging.getLogger(__name__)
1361+
1362+
sys.stderr.write(f"## create_signer wrapped_callback: context: {context}, data_ptr: {data_ptr}, data_len: {data_len}, signed_bytes_ptr: {signed_bytes_ptr}, signed_len: {signed_len}\n")
1363+
sys.stderr.flush()
1364+
logger.debug(f"create_signer wrapped_callback called: context={context}, data_len={data_len}, signed_len={signed_len}")
1365+
13221366
try:
1367+
if not data_ptr or data_len <= 0:
1368+
error_msg = f"Invalid input: data_ptr={data_ptr}, data_len={data_len}"
1369+
sys.stderr.write(f"## ERROR: {error_msg}\n")
1370+
sys.stderr.flush()
1371+
logger.error(error_msg)
1372+
return 0 # Error: invalid input
1373+
1374+
# Convert C pointer to Python bytes
1375+
data = bytes(data_ptr[:data_len])
1376+
sys.stderr.write(f"## Converted data: {len(data)} bytes\n")
1377+
sys.stderr.flush()
1378+
logger.debug(f"Converted data: {len(data)} bytes")
1379+
13231380
if not data:
1324-
raise ValueError("Empty data provided for signing")
1325-
return callback(data)
1381+
error_msg = "Empty data after conversion"
1382+
sys.stderr.write(f"## ERROR: {error_msg}\n")
1383+
sys.stderr.flush()
1384+
logger.error(error_msg)
1385+
return 0 # Error: empty data
1386+
1387+
# Call the user's callback
1388+
sys.stderr.write("## Calling user callback...\n")
1389+
sys.stderr.flush()
1390+
logger.debug("Calling user callback...")
1391+
signature = callback(data)
1392+
sys.stderr.write(f"## User callback returned: {len(signature) if signature else 0} bytes\n")
1393+
sys.stderr.flush()
1394+
logger.debug(f"User callback returned: {len(signature) if signature else 0} bytes")
1395+
1396+
if not signature:
1397+
error_msg = "User callback returned empty signature"
1398+
sys.stderr.write(f"## ERROR: {error_msg}\n")
1399+
sys.stderr.flush()
1400+
logger.error(error_msg)
1401+
return 0 # Error: empty signature
1402+
1403+
# Copy the signature back to the C buffer
1404+
actual_len = min(len(signature), signed_len)
1405+
sys.stderr.write(f"## Copying {actual_len} bytes to buffer (signature_len={len(signature)}, signed_len={signed_len})\n")
1406+
sys.stderr.flush()
1407+
logger.debug(f"Copying {actual_len} bytes to buffer")
1408+
1409+
for i in range(actual_len):
1410+
signed_bytes_ptr[i] = signature[i]
1411+
1412+
sys.stderr.write(f"## Successfully copied signature, returning {actual_len}\n")
1413+
sys.stderr.flush()
1414+
logger.debug(f"Successfully copied signature, returning {actual_len}")
1415+
return actual_len # Return the number of bytes written
13261416
except Exception as e:
1327-
print(
1328-
cls._error_messages['callback_error'].format(
1329-
str(e)), file=sys.stderr)
1330-
raise C2paError.Signature(str(e))
1417+
error_msg = f"Exception in wrapped_callback: {e}"
1418+
sys.stderr.write(f"## ERROR: {error_msg}\n")
1419+
sys.stderr.flush()
1420+
logger.error(error_msg)
1421+
return 0 # Return 0 to indicate error
13311422

13321423
# Encode strings with error handling
13331424
try:
@@ -1339,21 +1430,38 @@ def wrapped_callback(data: bytes) -> bytes:
13391430
str(e)))
13401431

13411432
# Create the signer with the wrapped callback
1433+
# Store the callback as an instance attribute to keep it alive
1434+
signer_instance = cls.__new__(cls)
1435+
signer_instance._callback_cb = SignerCallback(wrapped_callback)
1436+
1437+
sys.stderr.write("## About to call c2pa_signer_create from create_signer\n")
1438+
sys.stderr.flush()
1439+
logger.info("About to call c2pa_signer_create from create_signer")
1440+
13421441
signer_ptr = _lib.c2pa_signer_create(
13431442
None, # context
1344-
SignerCallback(wrapped_callback),
1443+
signer_instance._callback_cb,
13451444
alg,
13461445
certs_bytes,
13471446
tsa_url_bytes
13481447
)
13491448

1449+
sys.stderr.write(f"## c2pa_signer_create returned: {signer_ptr}\n")
1450+
sys.stderr.flush()
1451+
logger.info(f"c2pa_signer_create returned: {signer_ptr}")
1452+
13501453
if not signer_ptr:
13511454
error = _parse_operation_result_for_error(_lib.c2pa_error())
13521455
if error:
13531456
raise C2paError(error)
13541457
raise C2paError("Failed to create signer")
13551458

1356-
return cls(signer_ptr)
1459+
# Initialize the signer instance
1460+
signer_instance._signer = signer_ptr
1461+
signer_instance._closed = False
1462+
signer_instance._error_messages = cls._error_messages
1463+
1464+
return signer_instance
13571465

13581466
def __enter__(self):
13591467
"""Context manager entry."""
@@ -1895,25 +2003,116 @@ def create_signer(
18952003
C2paError: If there was an error creating the signer
18962004
C2paError.Encoding: If the certificate data or TSA URL contains invalid UTF-8 characters
18972005
"""
2006+
import logging
2007+
logger = logging.getLogger(__name__)
2008+
2009+
sys.stderr.write("## create_signer called\n")
2010+
sys.stderr.flush()
2011+
logger.info("create_signer called")
2012+
18982013
try:
18992014
certs_bytes = certs.encode('utf-8')
19002015
tsa_url_bytes = tsa_url.encode('utf-8') if tsa_url else None
19012016
except UnicodeError as e:
19022017
raise C2paError.Encoding(
19032018
f"Invalid UTF-8 characters in certificate data or TSA URL: {str(e)}")
19042019

2020+
sys.stderr.write("## About to call c2pa_signer_create from create_signer\n")
2021+
sys.stderr.flush()
2022+
logger.info("About to call c2pa_signer_create from create_signer")
2023+
2024+
# Create a wrapper callback that handles errors and memory management
2025+
def wrapped_callback(context, data_ptr, data_len, signed_bytes_ptr, signed_len):
2026+
logger = logging.getLogger(__name__)
2027+
2028+
sys.stderr.write(f"## create_signer wrapped_callback: context: {context}, data_ptr: {data_ptr}, data_len: {data_len}, signed_bytes_ptr: {signed_bytes_ptr}, signed_len: {signed_len}\n")
2029+
sys.stderr.flush()
2030+
logger.debug(f"create_signer wrapped_callback called: context={context}, data_len={data_len}, signed_len={signed_len}")
2031+
2032+
# Add immediate return for debugging
2033+
sys.stderr.write("## wrapped_callback entered - about to process\n")
2034+
sys.stderr.flush()
2035+
2036+
try:
2037+
if not data_ptr or data_len <= 0:
2038+
error_msg = f"Invalid input: data_ptr={data_ptr}, data_len={data_len}"
2039+
sys.stderr.write(f"## ERROR: {error_msg}\n")
2040+
sys.stderr.flush()
2041+
logger.error(error_msg)
2042+
return 0 # Error: invalid input
2043+
2044+
# Convert C pointer to Python bytes
2045+
data = bytes(data_ptr[:data_len])
2046+
sys.stderr.write(f"## Converted data: {len(data)} bytes\n")
2047+
sys.stderr.flush()
2048+
logger.debug(f"Converted data: {len(data)} bytes")
2049+
2050+
if not data:
2051+
error_msg = "Empty data after conversion"
2052+
sys.stderr.write(f"## ERROR: {error_msg}\n")
2053+
sys.stderr.flush()
2054+
logger.error(error_msg)
2055+
return 0 # Error: empty data
2056+
2057+
# Call the user's callback
2058+
sys.stderr.write("## Calling user callback...\n")
2059+
sys.stderr.flush()
2060+
logger.debug("Calling user callback...")
2061+
signature = callback(data)
2062+
sys.stderr.write(f"## User callback returned: {len(signature) if signature else 0} bytes\n")
2063+
sys.stderr.flush()
2064+
logger.debug(f"User callback returned: {len(signature) if signature else 0} bytes")
2065+
2066+
if not signature:
2067+
error_msg = "User callback returned empty signature"
2068+
sys.stderr.write(f"## ERROR: {error_msg}\n")
2069+
sys.stderr.flush()
2070+
logger.error(error_msg)
2071+
return 0 # Error: empty signature
2072+
2073+
# Copy the signature back to the C buffer
2074+
actual_len = min(len(signature), signed_len)
2075+
sys.stderr.write(f"## Copying {actual_len} bytes to buffer (signature_len={len(signature)}, signed_len={signed_len})\n")
2076+
sys.stderr.flush()
2077+
logger.debug(f"Copying {actual_len} bytes to buffer")
2078+
2079+
for i in range(actual_len):
2080+
signed_bytes_ptr[i] = signature[i]
2081+
2082+
sys.stderr.write(f"## Successfully copied signature, returning {actual_len}\n")
2083+
sys.stderr.flush()
2084+
logger.debug(f"Successfully copied signature, returning {actual_len}")
2085+
return actual_len # Return the number of bytes written
2086+
except Exception as e:
2087+
error_msg = f"Exception in wrapped_callback: {e}"
2088+
sys.stderr.write(f"## ERROR: {error_msg}\n")
2089+
sys.stderr.flush()
2090+
logger.error(error_msg)
2091+
return 0 # Return 0 to indicate error
2092+
2093+
# Store the callback to keep it alive
2094+
if not hasattr(create_signer, '_callbacks'):
2095+
create_signer._callbacks = []
2096+
2097+
# Create the C callback and store it
2098+
c_callback = SignerCallback(wrapped_callback)
2099+
create_signer._callbacks.append(c_callback) # Keep it alive
2100+
19052101
signer_ptr = _lib.c2pa_signer_create(
19062102
None, # context
1907-
SignerCallback(callback),
2103+
c_callback, # Use the stored callback
19082104
alg,
19092105
certs_bytes,
19102106
tsa_url_bytes
19112107
)
19122108

2109+
sys.stderr.write(f"## c2pa_signer_create returned: {signer_ptr}\n")
2110+
sys.stderr.flush()
2111+
logger.info(f"c2pa_signer_create returned: {signer_ptr}")
2112+
19132113
if not signer_ptr:
19142114
error = _parse_operation_result_for_error(_lib.c2pa_error())
19152115
if error:
1916-
# More detailed error message when possible
19172116
raise C2paError(error)
19182117
raise C2paError("Failed to create signer")
19192118

tests/test_unit_tests.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from unittest.mock import mock_open, patch
1919
import ctypes
2020
import warnings
21-
import pytest
2221
from cryptography.hazmat.primitives import hashes, serialization
2322
from cryptography.hazmat.primitives.asymmetric import padding
2423
from cryptography.hazmat.backends import default_backend
@@ -38,7 +37,7 @@
3837

3938
class TestC2paSdk(unittest.TestCase):
4039
def test_sdk_version(self):
41-
self.assertIn("0.55.0", sdk_version())
40+
self.assertIn("0.57.0", sdk_version())
4241

4342

4443
class TestReader(unittest.TestCase):
@@ -781,10 +780,13 @@ def sign_callback(data: bytes) -> bytes:
781780
)
782781

783782
# Create the signature using ES256 (ECDSA with SHA-256)
783+
# For ECDSA, we use the signature_algorithm_constructor
784+
from cryptography.hazmat.primitives import hashes
785+
from cryptography.hazmat.primitives.asymmetric import ec
786+
784787
signature = private_key.sign(
785788
data,
786-
padding=None, # ECDSA doesn't use padding
787-
algorithm=hashes.SHA256()
789+
ec.ECDSA(hashes.SHA256())
788790
)
789791

790792
return signature

0 commit comments

Comments
 (0)