Fix and document BIO_FLAGS_NONCLEAR_RST behavior on memory BIO
[oweals/openssl.git] / crypto / asn1 / tasn_fre.c
index f730d110bf929aa77e2ba7bf4c4dcbfe54ccaa35..bbce489fe0036d1aadbdd74beb730296083e7c37 100644 (file)
@@ -13,9 +13,6 @@
 #include <openssl/objects.h>
 #include "asn1_locl.h"
 
-static void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
-                                 int embed);
-
 /* Free up an ASN1 structure */
 
 void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
@@ -28,8 +25,7 @@ void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
     asn1_item_embed_free(pval, it, 0);
 }
 
-static void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
-                                 int embed)
+void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
 {
     const ASN1_TEMPLATE *tt = NULL, *seqtt;
     const ASN1_EXTERN_FUNCS *ef;
@@ -52,11 +48,11 @@ static void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
         if (it->templates)
             asn1_template_free(pval, it->templates);
         else
-            asn1_primitive_free(pval, it);
+            asn1_primitive_free(pval, it, embed);
         break;
 
     case ASN1_ITYPE_MSTRING:
-        asn1_primitive_free(pval, it);
+        asn1_primitive_free(pval, it, embed);
         break;
 
     case ASN1_ITYPE_CHOICE:
@@ -147,7 +143,7 @@ void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
     }
 }
 
-void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
 {
     int utype;
 
@@ -155,7 +151,12 @@ void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
     if (it) {
         const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
 
-        if (pf && pf->prim_free) {
+        if (embed) {
+            if (pf && pf->prim_clear) {
+                pf->prim_clear(pval, it);
+                return;
+            }
+        } else if (pf && pf->prim_free) {
             pf->prim_free(pval, it);
             return;
         }
@@ -195,12 +196,12 @@ void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
         break;
 
     case V_ASN1_ANY:
-        asn1_primitive_free(pval, NULL);
+        asn1_primitive_free(pval, NULL, 0);
         OPENSSL_free(*pval);
         break;
 
     default:
-        ASN1_STRING_free((ASN1_STRING *)*pval);
+        asn1_string_embed_free((ASN1_STRING *)*pval, embed);
         break;
     }
     *pval = NULL;