<p>If you look at <a href="https://github.com/bitcoin-core/secp256k1/blob/master/src/secp256k1.c" rel="nofollow noreferrer">the source code</a>, <code>secp256k1_ec_pubkey_parse</code> doesn't actually use its <code>ctx</code> argument.  So no harm is done if it's null.</p>

<p>You can see in the code that there is a <code>VERIFY_CHECK</code> macro to test if <code>ctx</code> is non-null.  However, this is meant only for testing; you can see in <a href="https://github.com/bitcoin-core/secp256k1/blob/master/src/util.h" rel="nofollow noreferrer">util.h</a> that nothing is actually done about the test unless the <code>VERIFY</code> macro is defined, which presumably is only the case for test builds.</p>

<p>The <code>SECP256K1_ARG_NONNULL</code> macro, defined <a href="https://github.com/bitcoin-core/secp256k1/blob/6e066962b7e4e9116194d7acd518da2ed2b7713f/include/secp256k1.h" rel="nofollow noreferrer">here</a>, uses the GCC <a href="https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html" rel="nofollow noreferrer">function attribute mechanism</a> to tell the compiler that this argument is supposed to be non-null.  The compiler will optimize on this basis.  It can try to issue a warning if it can determine, at compile time, that the argument is null; but only if you use the <code>-Wnonnull</code> option. </p>

CC BY-SA 3.0
2017-03-05T16:44:39.897Z
I think the macro `SECP256K1_BUILD` is probably defined during the build process, and this has the effect of reducing `SECP256K1_ARG_NONNULL(_x)` to the empty string, thereby removing the `__nonnull__` `gcc` attribute.
Sven Williamson
CC BY-SA 3.0
2017-03-05T16:26:24.020Z
2017-03-05T16:34:57.927Z
2017-03-05T16:34:57.927Z
Nate Eldredge
<p>Looking at the main API file <code>secp256k1.h</code> of the C library, we have:</p>

<pre><code>SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
    const secp256k1_context* ctx,
    secp256k1_pubkey* pubkey,
    const unsigned char *input,
    size_t inputlen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
</code></pre>

<p>Hence I am expecting the function <code>secp256k1_ec_pubkey_parse</code> to fail if any of the three pointer arguments are NULL. This is indeed the case when <code>pubkey</code> or <code>input</code> are <code>NULL</code> (and in fact if we set up a callback function with <code>secp256k1_context_set_illegal_callback</code>, it will be duly called with the appropriate return value). However <strong>this function succeeds on <code>NULL</code> context</strong>. Does anyone know why this is happening? Is this the expected behaviour? I am guessing this isn't very important, but I am trying to learn and I don't like it when I don't understand. I attach a C snippet:</p>

<pre><code>#include "secp256k1.h"
#include &lt;assert.h&gt;

int main()
{
  int return_value;

  secp256k1_context *ctx;         
  secp256k1_pubkey pub;           

  ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);

  // This is a valid public key
  const unsigned char *pub1 = "\x03"
    "\xf0\x28\x89\x2b\xad\x7e\xd5\x7d\x2f\xb5\x7b\xf3\x30\x81\xd5\xcf"
    "\xcf\x6f\x9e\xd3\xd3\xd7\xf1\x59\xc2\xe2\xff\xf5\x79\xdc\x34\x1a";

  // secp256k1_ec_pubkey_parse
  return_value = secp256k1_ec_pubkey_parse(ctx, &amp;pub, pub1, 33); 
  assert(return_value == 1);  // public key is indeed valid

  // same call with NULL context
  return_value = secp256k1_ec_pubkey_parse(NULL, &amp;pub, pub1, 33); 
  assert(return_value == 1);  // call is successfull

  // secp2561k1_context_destroy
 secp256k1_context_destroy(ctx);
}
</code></pre>

<secp256k1><c>
C secp256k1 : ec_pubkey_parse successful on NULL context despite attribute
Sven Williamson
# C secp256k1 : ec_pubkey_parse successful on NULL context despite attribute

(Asked by: username_0 on 2017-03-05)

Looking at the main API file `secp256k1.h` of the C library, we have:

```
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
    const secp256k1_context* ctx,
    secp256k1_pubkey* pubkey,
    const unsigned char *input,
    size_t inputlen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);

```

Hence I am expecting the function `secp256k1_ec_pubkey_parse` to fail if any of the three pointer arguments are NULL. This is indeed the case when `pubkey` or `input` are `NULL` (and in fact if we set up a callback function with `secp256k1_context_set_illegal_callback`, it will be duly called with the appropriate return value). However **this function succeeds on `NULL` context**. Does anyone know why this is happening? Is this the expected behaviour? I am guessing this isn't very important, but I am trying to learn and I don't like it when I don't understand. I attach a C snippet:

```
#include "secp256k1.h"
#include <assert.h>

int main()
{
  int return_value;

  secp256k1_context *ctx;         
  secp256k1_pubkey pub;           

  ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);

  // This is a valid public key
  const unsigned char *pub1 = "\x03"
    "\xf0\x28\x89\x2b\xad\x7e\xd5\x7d\x2f\xb5\x7b\xf3\x30\x81\xd5\xcf"
    "\xcf\x6f\x9e\xd3\xd3\xd7\xf1\x59\xc2\xe2\xff\xf5\x79\xdc\x34\x1a";

  // secp256k1_ec_pubkey_parse
  return_value = secp256k1_ec_pubkey_parse(ctx, &pub, pub1, 33); 
  assert(return_value == 1);  // public key is indeed valid

  // same call with NULL context
  return_value = secp256k1_ec_pubkey_parse(NULL, &pub, pub1, 33); 
  assert(return_value == 1);  // call is successfull

  // secp2561k1_context_destroy
 secp256k1_context_destroy(ctx);
}

```

**Tags:** secp256k1, c


---

## 1 answers

### Answer by username_1 on 2017-03-05. Score: 3 | Accepted answer

If you look at [the source code](https://github.com/bitcoin-core/secp256k1/blob/master/src/secp256k1.c), `secp256k1_ec_pubkey_parse` doesn't actually use its `ctx` argument. So no harm is done if it's null.

You can see in the code that there is a `VERIFY_CHECK` macro to test if `ctx` is non-null. However, this is meant only for testing; you can see in [util.h](https://github.com/bitcoin-core/secp256k1/blob/master/src/util.h) that nothing is actually done about the test unless the `VERIFY` macro is defined, which presumably is only the case for test builds.

The `SECP256K1_ARG_NONNULL` macro, defined [here](https://github.com/bitcoin-core/secp256k1/blob/6e066962b7e4e9116194d7acd518da2ed2b7713f/include/secp256k1.h), uses the GCC [function attribute mechanism](https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html) to tell the compiler that this argument is supposed to be non-null. The compiler will optimize on this basis. It can try to issue a warning if it can determine, at compile time, that the argument is null; but only if you use the `-Wnonnull` option.

> **Comments:**
> **username_0**: I think the macro `SECP256K1_BUILD` is probably defined during the build process, and this has the effect of reducing `SECP256K1_ARG_NONNULL(_x)` to the empty string, thereby removing the `__nonnull__` `gcc` attribute.  

---

