@@ -1320,21 +1320,27 @@ def from_callback(
13201320 # Create a wrapper callback that handles errors and memory management
13211321 def wrapped_callback (context , data_ptr , data_len , signed_bytes_ptr , signed_len ):
13221322 # Returns 0 on error as this case is handled in the native code gracefully
1323+ # The reason is that otherwise we ping-pong errors between native code and Python code,
1324+ # which can become tedious in handling. So we let the native code deal with it and
1325+ # raise the errors accordingly, since it already checks the signature length for correctness.
13231326 try :
13241327 if not data_ptr or data_len <= 0 :
1325- return 0 # Error: invalid input
1328+ # Error: invalid input, native code will handle if seeing signature size being 0
1329+ return 0
13261330
13271331 # Convert C pointer to Python bytes
13281332 data = bytes (data_ptr [:data_len ])
13291333 if not data :
1330- return 0 # Error: empty data, native code will handle it!
1334+ # Error: empty data, native code will handle it!
1335+ return 0
13311336
13321337 # Call the user's callback
13331338 signature = callback (data )
13341339 if not signature :
1335- return 0 # Error: empty signature, native code will handle that too!
1340+ # Error: empty signature, native code will handle that too!
1341+ return 0
13361342
1337- # Copy the signature back to the C buffer
1343+ # Copy the signature back to the C buffer (since callback is sued in native code)
13381344 actual_len = min (len (signature ), signed_len )
13391345 for i in range (actual_len ):
13401346 signed_bytes_ptr [i ] = signature [i ]
@@ -1347,7 +1353,7 @@ def wrapped_callback(context, data_ptr, data_len, signed_bytes_ptr, signed_len):
13471353 str (e )), file = sys .stderr )
13481354 return 0
13491355
1350- # Encode strings with error handling
1356+ # Encode strings with error handling in case it's invalid UTF8
13511357 try :
13521358 certs_bytes = certs .encode ('utf-8' )
13531359 tsa_url_bytes = tsa_url .encode ('utf-8' ) if tsa_url else None
@@ -1358,12 +1364,12 @@ def wrapped_callback(context, data_ptr, data_len, signed_bytes_ptr, signed_len):
13581364
13591365 # Create the signer with the wrapped callback
13601366 # Store the callback as an instance attribute to keep it alive, as this prevents
1361- # garbage colelction and lifetime issues.
1367+ # garbage collection and lifetime issues.
13621368 signer_instance = cls .__new__ (cls )
13631369 signer_instance ._callback_cb = SignerCallback (wrapped_callback )
13641370
13651371 signer_ptr = _lib .c2pa_signer_create (
1366- None , # context
1372+ None ,
13671373 signer_instance ._callback_cb ,
13681374 alg ,
13691375 certs_bytes ,
@@ -1950,22 +1956,22 @@ def wrapped_callback(context, data_ptr, data_len, signed_bytes_ptr, signed_len):
19501956
19511957 # Copy the signature back to the C buffer
19521958 actual_len = min (len (signature ), signed_len )
1953-
1959+
19541960 for i in range (actual_len ):
19551961 signed_bytes_ptr [i ] = signature [i ]
19561962
19571963 return actual_len # Return the number of bytes written
19581964 except Exception as e :
19591965 return 0 # Return 0 to indicate error
1960-
1966+
19611967 # Store the callback to keep it alive
19621968 if not hasattr (create_signer , '_callbacks' ):
19631969 create_signer ._callbacks = []
1964-
1970+
19651971 # Create the C callback and store it
19661972 c_callback = SignerCallback (wrapped_callback )
19671973 create_signer ._callbacks .append (c_callback ) # Keep it alive
1968-
1974+
19691975 signer_ptr = _lib .c2pa_signer_create (
19701976 None , # context
19711977 c_callback , # Use the stored callback
0 commit comments