From 1e5f9942e7bee50317434998f1b0690efa340a7f Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Fri, 13 Jan 2012 17:35:30 +0000 Subject: [PATCH] Simplify integer loading in ASN.1 encoding Instead of defining an auxiliary load function for each integer type, just use its size and signedness to decide how to load it. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25651 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/asn.1/asn1_encode.c | 38 +++++++++++++++++++++++--------- src/lib/krb5/asn.1/asn1_encode.h | 37 +++++-------------------------- 2 files changed, 34 insertions(+), 41 deletions(-) diff --git a/src/lib/krb5/asn.1/asn1_encode.c b/src/lib/krb5/asn.1/asn1_encode.c index ba71add15..e579bb007 100644 --- a/src/lib/krb5/asn.1/asn1_encode.c +++ b/src/lib/krb5/asn.1/asn1_encode.c @@ -231,6 +231,30 @@ encode_nullterm_sequence_of(asn1buf *buf, const void *val, return encode_sequence_of(buf, length, val, type, retlen); } +static asn1_intmax +load_int(const void *val, size_t size) +{ + switch (size) { + case 1: return *(signed char *)val; + case 2: return *(krb5_int16 *)val; + case 4: return *(krb5_int32 *)val; + case 8: return *(INT64_TYPE *)val; + default: abort(); + } +} + +static asn1_uintmax +load_uint(const void *val, size_t size) +{ + switch (size) { + case 1: return *(unsigned char *)val; + case 2: return *(krb5_ui_2 *)val; + case 4: return *(krb5_ui_4 *)val; + case 8: return *(UINT64_TYPE *)val; + default: abort(); + } +} + static asn1_error_code just_encode_sequence(asn1buf *buf, const void *val, const struct seq_info *seq, @@ -314,9 +338,7 @@ krb5int_asn1_encode_type(asn1buf *buf, const void *val, break; } case atype_int: { - const struct int_info *tinfo = a->tinfo; - assert(tinfo->loadint != NULL); - retval = asn1_encode_integer(buf, tinfo->loadint(val), + retval = asn1_encode_integer(buf, load_int(val, a->size), &rettag->length); if (retval) return retval; @@ -326,9 +348,7 @@ krb5int_asn1_encode_type(asn1buf *buf, const void *val, break; } case atype_uint: { - const struct uint_info *tinfo = a->tinfo; - assert(tinfo->loaduint != NULL); - retval = asn1_encode_unsigned_integer(buf, tinfo->loaduint(val), + retval = asn1_encode_unsigned_integer(buf, load_uint(val, a->size), &rettag->length); if (retval) return retval; @@ -385,8 +405,7 @@ get_field_len(const void *val, const struct field_info *field, assert(sizeof(int) <= sizeof(asn1_intmax)); assert(sizeof(unsigned int) <= sizeof(asn1_uintmax)); if (field->lentype->type == atype_int) { - const struct int_info *tinfo = field->lentype->tinfo; - asn1_intmax xlen = tinfo->loadint(lenptr); + asn1_intmax xlen = load_int(lenptr, field->lentype->size); if (xlen < 0) return EINVAL; if ((unsigned int)xlen != (asn1_uintmax)xlen) @@ -395,8 +414,7 @@ get_field_len(const void *val, const struct field_info *field, return EINVAL; *retlen = (unsigned int)xlen; } else { - const struct uint_info *tinfo = field->lentype->tinfo; - asn1_uintmax xlen = tinfo->loaduint(lenptr); + asn1_uintmax xlen = load_uint(lenptr, field->lentype->size); if ((unsigned int)xlen != xlen) return EINVAL; if (xlen > UINT_MAX) diff --git a/src/lib/krb5/asn.1/asn1_encode.h b/src/lib/krb5/asn.1/asn1_encode.h index 77d34f425..cd7983ac7 100644 --- a/src/lib/krb5/asn.1/asn1_encode.h +++ b/src/lib/krb5/asn.1/asn1_encode.h @@ -223,9 +223,8 @@ enum atype_type { atype_field, /* Tagged version of another type. tinfo is a struct tagged_info *. */ atype_tagged_thing, - /* Integer. tinfo is a struct int_info. */ + /* Signed or unsigned integer. tinfo is NULL. */ atype_int, - /* Unsigned integer. tinfo is a struct uint_info. */ atype_uint, /* Unused except for bounds checking. */ atype_max @@ -263,14 +262,6 @@ struct tagged_info { const struct atype_info *basetype; }; -struct int_info { - asn1_intmax (*loadint)(const void *); -}; - -struct uint_info { - asn1_uintmax (*loaduint)(const void *); -}; - /* * The various DEF*TYPE macros must: * @@ -399,31 +390,15 @@ struct uint_info { atype_choice, sizeof(CTYPENAME), &aux_seqinfo_##DESCNAME \ } /* Integer types. */ -#define DEFINTTYPE(DESCNAME, CTYPENAME) \ - typedef CTYPENAME aux_typedefname_##DESCNAME; \ - static asn1_intmax loadint_##DESCNAME(const void *p) \ - { \ - assert(sizeof(CTYPENAME) <= sizeof(asn1_intmax)); \ - return *(const aux_typedefname_##DESCNAME *)p; \ - } \ - static const struct int_info aux_info_##DESCNAME = { \ - loadint_##DESCNAME \ - }; \ - const struct atype_info krb5int_asn1type_##DESCNAME = { \ - atype_int, sizeof(CTYPENAME), &aux_info_##DESCNAME \ +#define DEFINTTYPE(DESCNAME, CTYPENAME) \ + typedef CTYPENAME aux_typedefname_##DESCNAME; \ + const struct atype_info krb5int_asn1type_##DESCNAME = { \ + atype_int, sizeof(CTYPENAME), NULL \ } #define DEFUINTTYPE(DESCNAME, CTYPENAME) \ typedef CTYPENAME aux_typedefname_##DESCNAME; \ - static asn1_uintmax loaduint_##DESCNAME(const void *p) \ - { \ - assert(sizeof(CTYPENAME) <= sizeof(asn1_uintmax)); \ - return *(const aux_typedefname_##DESCNAME *)p; \ - } \ - static const struct uint_info aux_info_##DESCNAME = { \ - loaduint_##DESCNAME \ - }; \ const struct atype_info krb5int_asn1type_##DESCNAME = { \ - atype_uint, sizeof(CTYPENAME), &aux_info_##DESCNAME \ + atype_uint, sizeof(CTYPENAME), NULL \ } /* Pointers to other types, to be encoded as those other types. */ #ifdef POINTERS_ARE_ALL_THE_SAME -- 2.26.2