Reduce type-punning in ASN1_TYPE
ASN1_TYPE is a union of a bunch of pointer types. Often it takes a shorthand and accesses a->value.ptr directly. This is allowed in C, but not C++. Writing the switch/case barely takes more code, so just write it that way. Along the way, extract the code for cleaning up an ASN1_TYPE from tasn_fre.c. This is a small step towards being able to use crypto/asn1's types without depending on the templates. ASN1_TYPE_free still, for now, calls into the templates. That will be fixable once tasn_*.c are rewritten a bit further. This also removes the weird hack here ASN1_primitive_free (an internal function) with NULL ASN1_ITEM secretly meant to partially clean up the ASN1_TYPE. We can just call the function directly now. Bug: 574 Change-Id: Ie2ba41418801a366ab2f12eccc01e8dadf82c33e Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58126 Reviewed-by: Bob Beck <bbe@google.com> Commit-Queue: David Benjamin <davidben@google.com>
This commit is contained in:
parent
6a231e5c6e
commit
860cc73bb2
@ -65,31 +65,65 @@
|
||||
|
||||
|
||||
int ASN1_TYPE_get(const ASN1_TYPE *a) {
|
||||
if (a->type == V_ASN1_BOOLEAN || a->type == V_ASN1_NULL ||
|
||||
a->value.ptr != NULL) {
|
||||
return a->type;
|
||||
switch (a->type) {
|
||||
case V_ASN1_NULL:
|
||||
case V_ASN1_BOOLEAN:
|
||||
return a->type;
|
||||
case V_ASN1_OBJECT:
|
||||
return a->value.object != NULL ? a->type : 0;
|
||||
default:
|
||||
return a->value.asn1_string != NULL ? a->type : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const void *asn1_type_value_as_pointer(const ASN1_TYPE *a) {
|
||||
if (a->type == V_ASN1_BOOLEAN) {
|
||||
return a->value.boolean ? (void *)0xff : NULL;
|
||||
switch (a->type) {
|
||||
case V_ASN1_NULL:
|
||||
return NULL;
|
||||
case V_ASN1_BOOLEAN:
|
||||
return a->value.boolean ? (void *)0xff : NULL;
|
||||
case V_ASN1_OBJECT:
|
||||
return a->value.object;
|
||||
default:
|
||||
return a->value.asn1_string;
|
||||
}
|
||||
if (a->type == V_ASN1_NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void asn1_type_cleanup(ASN1_TYPE *a) {
|
||||
switch (a->type) {
|
||||
case V_ASN1_NULL:
|
||||
a->value.ptr = NULL;
|
||||
break;
|
||||
case V_ASN1_BOOLEAN:
|
||||
a->value.boolean = ASN1_BOOLEAN_NONE;
|
||||
break;
|
||||
case V_ASN1_OBJECT:
|
||||
ASN1_OBJECT_free(a->value.object);
|
||||
a->value.object = NULL;
|
||||
break;
|
||||
default:
|
||||
ASN1_STRING_free(a->value.asn1_string);
|
||||
a->value.asn1_string = NULL;
|
||||
break;
|
||||
}
|
||||
return a->value.ptr;
|
||||
}
|
||||
|
||||
void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) {
|
||||
ASN1_TYPE **tmp_a = &a;
|
||||
ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
|
||||
asn1_type_cleanup(a);
|
||||
a->type = type;
|
||||
if (type == V_ASN1_BOOLEAN) {
|
||||
a->value.boolean = value ? 0xff : 0;
|
||||
} else {
|
||||
a->value.ptr = value;
|
||||
switch (type) {
|
||||
case V_ASN1_NULL:
|
||||
a->value.ptr = NULL;
|
||||
break;
|
||||
case V_ASN1_BOOLEAN:
|
||||
a->value.boolean = value ? ASN1_BOOLEAN_TRUE : ASN1_BOOLEAN_FALSE;
|
||||
break;
|
||||
case V_ASN1_OBJECT:
|
||||
a->value.object = value;
|
||||
break;
|
||||
default:
|
||||
a->value.asn1_string = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,6 +210,10 @@ void asn1_encoding_clear(ASN1_ENCODING *enc);
|
||||
// a pointer.
|
||||
const void *asn1_type_value_as_pointer(const ASN1_TYPE *a);
|
||||
|
||||
// asn1_type_cleanup releases memory associated with |a|'s value, without
|
||||
// freeing |a| itself.
|
||||
void asn1_type_cleanup(ASN1_TYPE *a);
|
||||
|
||||
// asn1_is_printable returns one if |value| is a valid Unicode codepoint for an
|
||||
// ASN.1 PrintableString, and zero otherwise.
|
||||
int asn1_is_printable(uint32_t value);
|
||||
|
@ -161,12 +161,10 @@ void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) {
|
||||
}
|
||||
|
||||
void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) {
|
||||
size_t i;
|
||||
if (tt->flags & ASN1_TFLG_SK_MASK) {
|
||||
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
|
||||
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
|
||||
ASN1_VALUE *vtmp;
|
||||
vtmp = sk_ASN1_VALUE_value(sk, i);
|
||||
for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
|
||||
ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i);
|
||||
ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
|
||||
}
|
||||
sk_ASN1_VALUE_free(sk);
|
||||
@ -177,30 +175,11 @@ void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) {
|
||||
}
|
||||
|
||||
void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) {
|
||||
int utype;
|
||||
// Historically, |it->funcs| for primitive types contained an
|
||||
// |ASN1_PRIMITIVE_FUNCS| table of calbacks.
|
||||
assert(it == NULL || it->funcs == NULL);
|
||||
// Special case: if 'it' is NULL free contents of ASN1_TYPE
|
||||
if (!it) {
|
||||
ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
|
||||
utype = typ->type;
|
||||
pval = &typ->value.asn1_value;
|
||||
if (utype != V_ASN1_BOOLEAN && !*pval) {
|
||||
return;
|
||||
}
|
||||
} else if (it->itype == ASN1_ITYPE_MSTRING) {
|
||||
utype = -1;
|
||||
if (!*pval) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
utype = it->utype;
|
||||
if ((utype != V_ASN1_BOOLEAN) && !*pval) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(it->funcs == NULL);
|
||||
|
||||
int utype = it->itype == ASN1_ITYPE_MSTRING ? -1 : it->utype;
|
||||
switch (utype) {
|
||||
case V_ASN1_OBJECT:
|
||||
ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
|
||||
@ -210,7 +189,7 @@ void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) {
|
||||
if (it) {
|
||||
*(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size;
|
||||
} else {
|
||||
*(ASN1_BOOLEAN *)pval = -1;
|
||||
*(ASN1_BOOLEAN *)pval = ASN1_BOOLEAN_NONE;
|
||||
}
|
||||
return;
|
||||
|
||||
@ -218,8 +197,10 @@ void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) {
|
||||
break;
|
||||
|
||||
case V_ASN1_ANY:
|
||||
ASN1_primitive_free(pval, NULL);
|
||||
OPENSSL_free(*pval);
|
||||
if (*pval != NULL) {
|
||||
asn1_type_cleanup((ASN1_TYPE *)*pval);
|
||||
OPENSSL_free(*pval);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user