Hello. I use callback feature of CFFI. I want to use an encoding as a default and if I get an invalid string (non-UTF-8 in my case), I'd just reject it by returning an error. Unfortunately, if I declare string arguments with encoding, attempts by CFFI to decode the string raise an error which prevents me from returning protocol-compliant error to the caller.
The context: I currently work on FUSE bindings for Common Lisp (or at least SBCL for now). In case of error occurring in my code, I return EIO. Of course, for invalid file names I want to return either EIO or ENOENT. Currently, request just hangs.
This can be mitigated by patching CFFI. If I just wrap the conversion in ignore-errors, I lose the distinction between an invalid string and null pointer, but I get a chance to process the request (both cases are wrong in my case). Specifying a designated "wrong string object" and letting user change it seems to be the nicest way: the user gets an error on trying to use the object as a string, but user code can handle it nicely.
I changed the following in string conversion code:
(defmethod translate-from-foreign (ptr (type foreign-string-type)) (unwind-protect (block nil (handler-case (values (foreign-string-to-lisp ptr :encoding (fst-encoding type))) (error (x) (return t)) )) (when (fst-free-from-foreign-p type) (foreign-free ptr))))
That allowed me to handle invalid requests to the FS by returning ENOENT (just as originally intended).
Would you please consider adding some similar modification in official CFFI repository?
Michael Raskin
Hello Michael,
Sorry for the late reply.
On Fri, Mar 19, 2010 at 8:05 AM, Michael Raskin f9cef2aa@yandex.ru wrote:
I use callback feature of CFFI. I want to use an encoding as a default and if I get an invalid string (non-UTF-8 in my case), I'd just reject it by returning an error. Unfortunately, if I declare string arguments with encoding, attempts by CFFI to decode the string raise an error which prevents me from returning protocol-compliant error to the caller.
[...]
This can be mitigated by patching CFFI. If I just wrap the conversion in ignore-errors, I lose the distinction between an invalid string and null pointer, but I get a chance to process the request (both cases are wrong in my case).
[...]
Would you please consider adding some similar modification in official CFFI repository?
One way to handle this issue is the following:
(let ((babel-encodings:*suppress-character-coding-errors* t)) (foreign-string-alloc "pão" :encoding :ascii))
But I'm not sure whether this is applicable in your case. The proper solution to this issue is to add some sort of :ignore-errors parameter to foreign-string-alloc and to the :string type. I've registered this wishlist item in http://bugs.launchpad.net/cffi/+bug/622421.
Cheers,