[PATCH gpgme] Fix error handling in _gpgme_parse_status().

Xi Wang xi.wang at gmail.com
Thu Nov 15 19:20:35 CET 2012


On 11/15/12 5:09 AM, Werner Koch wrote:
> On Thu, 15 Nov 2012 09:27, xi.wang at gmail.com said:
> 
>> Even though _gpgme_parse_status() returns -1 on error, the return type
>> gpgme_status_code_t is unsigned, and thus (r >= 0) is always true.
> 
> How do you come to the impression that gpgme_status_code_t is an
> unsigned integer?  It is an enumeration and those are compatible with a
> (signed) integer.  Although some systems use different sizes for the
> enumeration integer type, I have never seen a claim that it is unsigned.

The storage of an enum is compatible with int, but the signedness is
very tricky.

Most compilers seem to decide the signedness of an enum type based on
its value range: if all the enum values are non-negative (such as
GPGME_STATUS_*), then the enum type is _unsigned_.

Check out the assembly of the code below, using gcc/clang/icc on x86.

  typedef enum {
    GPGME_STATUS_EOF = 0,
    GPGME_STATUS_ENTER = 1,
    GPGME_STATUS_DECRYPTION_INFO = 85
  } gpgme_status_code_t;

  int foo(gpgme_status_code_t code)
  {
    return code >= 0;
  }

The resulting assembly is:

  movl	$1, %eax
  ret

It means gpgme_status_code_t is treated as unsigned.

We could add -1 to the enum value set; in that case compilers considers
the enum type as signed.

> What is the problem you want solve?

The function _gpgme_parse_status() returns a gpgme_status_code_t, and
it also returns -1 on error.

Some client code treats the return type as signed for error handling
(see readstatus() at src/engine-gpg.c:1034), which doesn't work.

It's better to fix this by changing the return type to signed int, or
adding -1 to the enum value set.

- xi



More information about the Gnupg-devel mailing list