crypto/x509/v3_purp.c:174: error: NULL_DEREFERENCE
  pointer `ptmp` last assigned on line 171 could be null and is dereferenced at line 174, column 9.
Showing all 34 steps of the trace


crypto/x509/v3_purp.c:149:1: start of procedure X509_PURPOSE_add()
147.   }
148.   
149. > int X509_PURPOSE_add(int id, int trust, int flags,
150.                        int (*ck) (const X509_PURPOSE *, const X509 *, int),
151.                        const char *name, const char *sname, void *arg)

crypto/x509/v3_purp.c:158:5: 
156.        * This is set according to what we change: application can't set it
157.        */
158. >     flags &= ~X509_PURPOSE_DYNAMIC;
159.       /* This will always be set for application modified trust entries */
160.       flags |= X509_PURPOSE_DYNAMIC_NAME;

crypto/x509/v3_purp.c:160:5: 
158.       flags &= ~X509_PURPOSE_DYNAMIC;
159.       /* This will always be set for application modified trust entries */
160. >     flags |= X509_PURPOSE_DYNAMIC_NAME;
161.       /* Get existing entry if any */
162.       idx = X509_PURPOSE_get_by_id(id);

crypto/x509/v3_purp.c:162:5: 
160.       flags |= X509_PURPOSE_DYNAMIC_NAME;
161.       /* Get existing entry if any */
162. >     idx = X509_PURPOSE_get_by_id(id);
163.       /* Need a new entry */
164.       if (idx == -1) {

crypto/x509/v3_purp.c:133:1: start of procedure X509_PURPOSE_get_by_id()
  131.   }
  132.   
  133. > int X509_PURPOSE_get_by_id(int purpose)
  134.   {
  135.       X509_PURPOSE tmp;

crypto/x509/v3_purp.c:138:10: Taking true branch
  136.       int idx;
  137.   
  138.       if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
                  ^
  139.           return purpose - X509_PURPOSE_MIN;
  140.       if (xptable == NULL)

crypto/x509/v3_purp.c:138:43: Taking false branch
  136.       int idx;
  137.   
  138.       if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
                                                   ^
  139.           return purpose - X509_PURPOSE_MIN;
  140.       if (xptable == NULL)

crypto/x509/v3_purp.c:140:9: Taking false branch
  138.       if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
  139.           return purpose - X509_PURPOSE_MIN;
  140.       if (xptable == NULL)
                 ^
  141.           return -1;
  142.       tmp.purpose = purpose;

crypto/x509/v3_purp.c:142:5: 
  140.       if (xptable == NULL)
  141.           return -1;
  142. >     tmp.purpose = purpose;
  143.       idx = sk_X509_PURPOSE_find(xptable, &tmp);
  144.       if (idx < 0)

crypto/x509/v3_purp.c:143:5: 
  141.           return -1;
  142.       tmp.purpose = purpose;
  143. >     idx = sk_X509_PURPOSE_find(xptable, &tmp);
  144.       if (idx < 0)
  145.           return -1;

include/openssl/x509v3.h:448:1: start of procedure sk_X509_PURPOSE_find()
    446.   # define X509V3_ADD_SILENT               0x10
    447.   
    448. > DEFINE_STACK_OF(X509_PURPOSE)
    449.   
    450.   DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)

crypto/stack/stack.c:315:1: start of procedure OPENSSL_sk_find()
      313.   }
      314.   
      315. > int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)
      316.   {
      317.       return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH);

crypto/stack/stack.c:317:5: 
      315.   int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)
      316.   {
      317. >     return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH);
      318.   }
      319.   

crypto/stack/stack.c:286:1: start of procedure internal_find()
        284.   }
        285.   
        286. > static int internal_find(OPENSSL_STACK *st, const void *data,
        287.                            int ret_val_options)
        288.   {

crypto/stack/stack.c:292:9: Taking false branch
        290.       int i;
        291.   
        292.       if (st == NULL || st->num == 0)
                       ^
        293.           return -1;
        294.   

crypto/stack/stack.c:292:23: Taking false branch
        290.       int i;
        291.   
        292.       if (st == NULL || st->num == 0)
                                     ^
        293.           return -1;
        294.   

crypto/stack/stack.c:295:9: Taking true branch
        293.           return -1;
        294.   
        295.       if (st->comp == NULL) {
                       ^
        296.           for (i = 0; i < st->num; i++)
        297.               if (st->data[i] == data)

crypto/stack/stack.c:296:14: 
        294.   
        295.       if (st->comp == NULL) {
        296. >         for (i = 0; i < st->num; i++)
        297.               if (st->data[i] == data)
        298.                   return i;

crypto/stack/stack.c:296:21: Loop condition is true. Entering loop body
        294.   
        295.       if (st->comp == NULL) {
        296.           for (i = 0; i < st->num; i++)
                                   ^
        297.               if (st->data[i] == data)
        298.                   return i;

crypto/stack/stack.c:297:17: Taking true branch
        295.       if (st->comp == NULL) {
        296.           for (i = 0; i < st->num; i++)
        297.               if (st->data[i] == data)
                               ^
        298.                   return i;
        299.           return -1;

crypto/stack/stack.c:298:17: 
        296.           for (i = 0; i < st->num; i++)
        297.               if (st->data[i] == data)
        298. >                 return i;
        299.           return -1;
        300.       }

crypto/stack/stack.c:313:1: return from a call to internal_find
        311.   
        312.       return r == NULL ? -1 : (int)((const void **)r - st->data);
        313. > }
        314.   
        315.   int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)

crypto/stack/stack.c:318:1: return from a call to OPENSSL_sk_find
      316.   {
      317.       return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH);
      318. > }
      319.   
      320.   int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data)

include/openssl/x509v3.h:448:1: return from a call to sk_X509_PURPOSE_find
    446.   # define X509V3_ADD_SILENT               0x10
    447.   
    448. > DEFINE_STACK_OF(X509_PURPOSE)
    449.   
    450.   DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)

crypto/x509/v3_purp.c:144:9: Taking false branch
  142.       tmp.purpose = purpose;
  143.       idx = sk_X509_PURPOSE_find(xptable, &tmp);
  144.       if (idx < 0)
                 ^
  145.           return -1;
  146.       return idx + X509_PURPOSE_COUNT;

crypto/x509/v3_purp.c:146:5: 
  144.       if (idx < 0)
  145.           return -1;
  146. >     return idx + X509_PURPOSE_COUNT;
  147.   }
  148.   

crypto/x509/v3_purp.c:147:1: return from a call to X509_PURPOSE_get_by_id
  145.           return -1;
  146.       return idx + X509_PURPOSE_COUNT;
  147. > }
  148.   
  149.   int X509_PURPOSE_add(int id, int trust, int flags,

crypto/x509/v3_purp.c:164:9: Taking false branch
162.       idx = X509_PURPOSE_get_by_id(id);
163.       /* Need a new entry */
164.       if (idx == -1) {
               ^
165.           if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) {
166.               X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);

crypto/x509/v3_purp.c:171:9: 
169.           ptmp->flags = X509_PURPOSE_DYNAMIC;
170.       } else
171. >         ptmp = X509_PURPOSE_get0(idx);
172.   
173.       /* OPENSSL_free existing name if dynamic */

crypto/x509/v3_purp.c:112:1: start of procedure X509_PURPOSE_get0()
  110.   }
  111.   
  112. > X509_PURPOSE *X509_PURPOSE_get0(int idx)
  113.   {
  114.       if (idx < 0)

crypto/x509/v3_purp.c:114:9: Taking true branch
  112.   X509_PURPOSE *X509_PURPOSE_get0(int idx)
  113.   {
  114.       if (idx < 0)
                 ^
  115.           return NULL;
  116.       if (idx < (int)X509_PURPOSE_COUNT)

crypto/x509/v3_purp.c:115:9: 
  113.   {
  114.       if (idx < 0)
  115. >         return NULL;
  116.       if (idx < (int)X509_PURPOSE_COUNT)
  117.           return xstandard + idx;

crypto/x509/v3_purp.c:119:1: return from a call to X509_PURPOSE_get0
  117.           return xstandard + idx;
  118.       return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
  119. > }
  120.   
  121.   int X509_PURPOSE_get_by_sname(const char *sname)

crypto/x509/v3_purp.c:174:9: 
172.   
173.       /* OPENSSL_free existing name if dynamic */
174. >     if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
175.           OPENSSL_free(ptmp->name);
176.           OPENSSL_free(ptmp->sname);

int X509_PURPOSE_add(int id, int trust, int flags,
                     int (*ck) (const X509_PURPOSE *, const X509 *, int),
                     const char *name, const char *sname, void *arg)
{
    int idx;
    X509_PURPOSE *ptmp;
    flags &= ~X509_PURPOSE_DYNAMIC;
    flags |= X509_PURPOSE_DYNAMIC_NAME;
    idx = X509_PURPOSE_get_by_id(id);
    if (idx == -1) {
        if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) {
            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
            return 0;
        }
        ptmp->flags = X509_PURPOSE_DYNAMIC;
    } else
        ptmp = X509_PURPOSE_get0(idx);
    if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
        OPENSSL_free(ptmp->name);
        OPENSSL_free(ptmp->sname);
    }
    ptmp->name = OPENSSL_strdup(name);
    ptmp->sname = OPENSSL_strdup(sname);
    if (!ptmp->name || !ptmp->sname) {
        X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    ptmp->flags &= X509_PURPOSE_DYNAMIC;
    ptmp->flags |= flags;
    ptmp->purpose = id;
    ptmp->trust = trust;
    ptmp->check_purpose = ck;
    ptmp->usr_data = arg;
    if (idx == -1) {
        if (xptable == NULL
            && (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) {
            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
            goto err;
        }
    }
    return 1;
 err:
    if (idx == -1) {
        OPENSSL_free(ptmp->name);
        OPENSSL_free(ptmp->sname);
        OPENSSL_free(ptmp);
    }
    return 0;
}
['int X509_PURPOSE_add(int id, int trust, int flags,\n                     int (*ck) (const X509_PURPOSE *, const X509 *, int),\n                     const char *name, const char *sname, void *arg)\n{\n    int idx;\n    X509_PURPOSE *ptmp;\n    flags &= ~X509_PURPOSE_DYNAMIC;\n    flags |= X509_PURPOSE_DYNAMIC_NAME;\n    idx = X509_PURPOSE_get_by_id(id);\n    if (idx == -1) {\n        if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) {\n            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);\n            return 0;\n        }\n        ptmp->flags = X509_PURPOSE_DYNAMIC;\n    } else\n        ptmp = X509_PURPOSE_get0(idx);\n    if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {\n        OPENSSL_free(ptmp->name);\n        OPENSSL_free(ptmp->sname);\n    }\n    ptmp->name = OPENSSL_strdup(name);\n    ptmp->sname = OPENSSL_strdup(sname);\n    if (!ptmp->name || !ptmp->sname) {\n        X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    ptmp->flags &= X509_PURPOSE_DYNAMIC;\n    ptmp->flags |= flags;\n    ptmp->purpose = id;\n    ptmp->trust = trust;\n    ptmp->check_purpose = ck;\n    ptmp->usr_data = arg;\n    if (idx == -1) {\n        if (xptable == NULL\n            && (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) {\n            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);\n            goto err;\n        }\n        if (!sk_X509_PURPOSE_push(xptable, ptmp)) {\n            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);\n            goto err;\n        }\n    }\n    return 1;\n err:\n    if (idx == -1) {\n        OPENSSL_free(ptmp->name);\n        OPENSSL_free(ptmp->sname);\n        OPENSSL_free(ptmp);\n    }\n    return 0;\n}', 'int X509_PURPOSE_get_by_id(int purpose)\n{\n    X509_PURPOSE tmp;\n    int idx;\n    if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))\n        return purpose - X509_PURPOSE_MIN;\n    if (xptable == NULL)\n        return -1;\n    tmp.purpose = purpose;\n    idx = sk_X509_PURPOSE_find(xptable, &tmp);\n    if (idx < 0)\n        return -1;\n    return idx + X509_PURPOSE_COUNT;\n}', 'DEFINE_STACK_OF(X509_PURPOSE)', 'int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)\n{\n    return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH);\n}', 'static int internal_find(OPENSSL_STACK *st, const void *data,\n                         int ret_val_options)\n{\n    const void *r;\n    int i;\n    if (st == NULL || st->num == 0)\n        return -1;\n    if (st->comp == NULL) {\n        for (i = 0; i < st->num; i++)\n            if (st->data[i] == data)\n                return i;\n        return -1;\n    }\n    if (!st->sorted) {\n        if (st->num > 1)\n            qsort(st->data, st->num, sizeof(void *), st->comp);\n        st->sorted = 1;\n    }\n    if (data == NULL)\n        return -1;\n    r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp,\n                     ret_val_options);\n    return r == NULL ? -1 : (int)((const void **)r - st->data);\n}', 'X509_PURPOSE *X509_PURPOSE_get0(int idx)\n{\n    if (idx < 0)\n        return NULL;\n    if (idx < (int)X509_PURPOSE_COUNT)\n        return xstandard + idx;\n    return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);\n}']