diff options
author | Kurt Roeckx <kurt@roeckx.be> | 2014-04-20 16:50:02 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2014-04-26 11:39:40 +0200 |
commit | 84288b43c80e7f555c1a0a2ed6b4f22bcdf6be41 (patch) | |
tree | d995e91ab64db177134997645ed592dfe4274c25 | |
parent | 057193dcc2089520ab36d95f42d12f4ffd8127b5 (diff) | |
download | libtasn1-84288b43c80e7f555c1a0a2ed6b4f22bcdf6be41.tar.gz libtasn1-84288b43c80e7f555c1a0a2ed6b4f22bcdf6be41.tar.bz2 libtasn1-84288b43c80e7f555c1a0a2ed6b4f22bcdf6be41.zip |
_asn1_ordering_*(): Fix memory leak in case of error
-rw-r--r-- | lib/coding.c | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/lib/coding.c b/lib/coding.c index fda94a7..4ed033f 100644 --- a/lib/coding.c +++ b/lib/coding.c @@ -714,6 +714,7 @@ _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) asn1_node p; unsigned char class, *temp; unsigned long tag, t; + int err; counter = 0; @@ -733,7 +734,10 @@ _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) { p_vet = malloc (sizeof (struct vet)); if (p_vet == NULL) - return ASN1_MEM_ALLOC_ERROR; + { + err = ASN1_MEM_ALLOC_ERROR; + goto error; + } p_vet->next = NULL; p_vet->prev = last; @@ -744,10 +748,10 @@ _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) last = p_vet; /* tag value calculation */ - if (asn1_get_tag_der - (der + counter, der_len - counter, &class, &len2, - &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; + err = asn1_get_tag_der (der + counter, der_len - counter, &class, &len2, + &tag); + if (err != ASN1_SUCCESS) + goto error; t = class << 24; p_vet->value = t | tag; @@ -756,7 +760,10 @@ _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) /* extraction and length */ len2 = asn1_get_length_der (der + counter, der_len - counter, &len); if (len2 < 0) - return ASN1_DER_ERROR; + { + err = ASN1_DER_ERROR; + goto error; + } counter += len + len2; p_vet->end = counter; @@ -776,7 +783,10 @@ _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) /* change position */ temp = malloc (p_vet->end - counter); if (temp == NULL) - return ASN1_MEM_ALLOC_ERROR; + { + err = ASN1_MEM_ALLOC_ERROR; + goto error; + } memcpy (temp, der + counter, p_vet->end - counter); memcpy (der + counter, der + p_vet->end, @@ -805,6 +815,15 @@ _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) p_vet = first; } return ASN1_SUCCESS; + +error: + while (first != NULL) + { + p_vet = first; + first = first->next; + free(p_vet); + } + return err; } /******************************************************/ @@ -832,6 +851,7 @@ _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node) asn1_node p; unsigned char *temp, class; unsigned long k, max; + int err; counter = 0; @@ -851,7 +871,10 @@ _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node) { p_vet = malloc (sizeof (struct vet)); if (p_vet == NULL) - return ASN1_MEM_ALLOC_ERROR; + { + err = ASN1_MEM_ALLOC_ERROR; + goto error; + } p_vet->next = NULL; p_vet->prev = last; @@ -865,15 +888,18 @@ _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node) if (der_len - counter > 0) { - if (asn1_get_tag_der - (der + counter, der_len - counter, &class, &len, - NULL) != ASN1_SUCCESS) - return ASN1_DER_ERROR; + err = asn1_get_tag_der (der + counter, der_len - counter, &class, + &len, NULL); + if (err != ASN1_SUCCESS) + goto error; counter += len; len2 = asn1_get_length_der (der + counter, der_len - counter, &len); if (len2 < 0) - return ASN1_DER_ERROR; + { + err = ASN1_DER_ERROR; + goto error; + } counter += len + len2; } @@ -916,7 +942,10 @@ _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node) /* change position */ temp = malloc (p_vet->end - counter); if (temp == NULL) - return ASN1_MEM_ALLOC_ERROR; + { + err = ASN1_MEM_ALLOC_ERROR; + goto error; + } memcpy (temp, der + counter, (p_vet->end) - counter); memcpy (der + counter, der + (p_vet->end), @@ -941,6 +970,15 @@ _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node) p_vet = first; } return ASN1_SUCCESS; + +error: + while (first != NULL) + { + p_vet = first; + first = first->next; + free(p_vet); + } + return err; } /** |