Cleanup after sk_push fail
[openssl.git] / crypto / x509 / x_name.c
index f0b35fb4fadc8916adfbc64bb16adb79eed22f8a..ebb66a1aef894ab6d53243d83e7fcf1cbf1725fe 100644 (file)
@@ -173,12 +173,26 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
         for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
             entry = sk_X509_NAME_ENTRY_value(entries, j);
             entry->set = i;
-            if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
+            if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) {
+                /*
+                 * Free all in entries if sk_X509_NAME_ENTRY_push return failure.
+                 * X509_NAME_ENTRY_free will check the null entry.
+                 */
+                sk_X509_NAME_ENTRY_pop_free(entries, X509_NAME_ENTRY_free);
                 goto err;
+            }
+            /*
+             * If sk_X509_NAME_ENTRY_push return success, clean the entries[j].
+             * It's necessary when 'goto err;' happens.
+             */
+            sk_X509_NAME_ENTRY_set(entries, j, NULL);
         }
         sk_X509_NAME_ENTRY_free(entries);
+        sk_STACK_OF_X509_NAME_ENTRY_set(intname.s, i, NULL);
     }
+
     sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
+    intname.s = NULL;
     ret = x509_name_canon(nm.x);
     if (!ret)
         goto err;
@@ -186,8 +200,10 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
     *val = nm.a;
     *in = p;
     return ret;
+
  err:
     X509_NAME_free(nm.x);
+    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, sk_X509_NAME_ENTRY_free);
     ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     return 0;
 }
@@ -322,6 +338,8 @@ static int x509_name_canon(X509_NAME *a)
         if (tmpentry == NULL)
             goto err;
         tmpentry->object = OBJ_dup(entry->object);
+        if (tmpentry->object == NULL)
+            goto err;
         if (!asn1_string_canon(tmpentry->value, entry->value))
             goto err;
         if (!sk_X509_NAME_ENTRY_push(entries, tmpentry))
@@ -396,10 +414,10 @@ static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
         len--;
     }
 
-    to = from + len - 1;
+    to = from + len;
 
     /* Ignore trailing spaces */
-    while ((len > 0) && !(*to & 0x80) && isspace(*to)) {
+    while ((len > 0) && !(to[-1] & 0x80) && isspace(to[-1])) {
         to--;
         len--;
     }