svn rev #25615: trunk/src/lib/krb5/asn.1/

ghudson@MIT.EDU ghudson at MIT.EDU
Fri Jan 6 16:10:43 EST 2012


http://src.mit.edu/fisheye/changelog/krb5/?cs=25615
Commit By: ghudson
Log Message:
Factor out length retrieval in ASN.1 encoder


Changed Files:
U   trunk/src/lib/krb5/asn.1/asn1_encode.c
Modified: trunk/src/lib/krb5/asn.1/asn1_encode.c
===================================================================
--- trunk/src/lib/krb5/asn.1/asn1_encode.c	2012-01-06 21:08:54 UTC (rev 25614)
+++ trunk/src/lib/krb5/asn.1/asn1_encode.c	2012-01-06 21:10:42 UTC (rev 25615)
@@ -191,10 +191,10 @@
     (assert((PTRINFO)->loadptr != NULL), (PTRINFO)->loadptr(PTR))
 #endif
 
-static int
+static unsigned int
 get_nullterm_sequence_len(const void *valp, const struct atype_info *seq)
 {
-    int i;
+    unsigned int i;
     const struct atype_info *a;
     const struct ptr_info *ptr;
     const void *elt, *eltptr;
@@ -215,7 +215,7 @@
     return i;
 }
 static asn1_error_code
-encode_sequence_of(asn1buf *buf, int seqlen, const void *val,
+encode_sequence_of(asn1buf *buf, unsigned int seqlen, const void *val,
                    const struct atype_info *eltinfo,
                    unsigned int *retlen);
 
@@ -225,7 +225,7 @@
                             int can_be_empty,
                             unsigned int *retlen)
 {
-    int length = get_nullterm_sequence_len(val, type);
+    unsigned int length = get_nullterm_sequence_len(val, type);
     if (!can_be_empty && length == 0) return ASN1_MISSING_FIELD;
     return encode_sequence_of(buf, length, val, type, retlen);
 }
@@ -372,6 +372,39 @@
  * construction bit instead (only valid if the field has no context tag).
  */
 static asn1_error_code
+get_field_len(const void *val, const struct field_info *field,
+              unsigned int *retlen)
+{
+    const void *lenptr = (const char *)val + field->lenoff;
+
+    assert(field->lentype != NULL);
+    assert(field->lentype->type == atype_int ||
+           field->lentype->type == atype_uint);
+    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);
+        if (xlen < 0)
+            return EINVAL;
+        if ((unsigned int)xlen != (asn1_uintmax)xlen)
+            return EINVAL;
+        if ((unsigned int)xlen > UINT_MAX)
+            return EINVAL;
+        *retlen = (unsigned int)xlen;
+    } else {
+        const struct uint_info *tinfo = field->lentype->tinfo;
+        asn1_uintmax xlen = tinfo->loaduint(lenptr);
+        if ((unsigned int)xlen != xlen)
+            return EINVAL;
+        if (xlen > UINT_MAX)
+            return EINVAL;
+        *retlen = (unsigned int)xlen;
+    }
+    return 0;
+}
+
+static asn1_error_code
 encode_a_field(asn1buf *buf, const void *val, const struct field_info *field,
                unsigned int *retlen, asn1_construction *omit_tag)
 {
@@ -405,9 +438,8 @@
     }
     case field_sequenceof_len:
     {
-        const void *dataptr, *lenptr;
-        int slen;
-        const struct atype_info *a;
+        const void *dataptr = (const char *)val + field->dataoff;
+        unsigned int slen;
         const struct ptr_info *ptrinfo;
 
         /*
@@ -415,38 +447,16 @@
          * address we compute is a pointer-to-pointer, and that's what
          * field->atype must help us dereference.
          */
-        dataptr = (const char *)val + field->dataoff;
-        lenptr = (const char *)val + field->lenoff;
         assert(field->atype->type == atype_ptr);
         ptrinfo = field->atype->tinfo;
         dataptr = LOADPTR(dataptr, ptrinfo);
-        a = ptrinfo->basetype;
-        assert(field->lentype != 0);
-        assert(field->lentype->type == atype_int || field->lentype->type == atype_uint);
-        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);
-            if (xlen < 0)
-                return EINVAL;
-            if ((unsigned int) xlen != (asn1_uintmax) xlen)
-                return EINVAL;
-            if ((unsigned int) xlen > INT_MAX)
-                return EINVAL;
-            slen = (int) xlen;
-        } else {
-            const struct uint_info *tinfo = field->lentype->tinfo;
-            asn1_uintmax xlen = tinfo->loaduint(lenptr);
-            if ((unsigned int) xlen != xlen)
-                return EINVAL;
-            if (xlen > INT_MAX)
-                return EINVAL;
-            slen = (int) xlen;
-        }
+        retval = get_field_len(val, field, &slen);
+        if (retval)
+            return retval;
         if (slen != 0 && dataptr == NULL)
             return ASN1_MISSING_FIELD;
-        retval = encode_sequence_of(buf, slen, dataptr, a, &length);
+        retval = encode_sequence_of(buf, slen, dataptr, ptrinfo->basetype,
+                                    &length);
         if (retval)
             return retval;
         construction = CONSTRUCTED;
@@ -469,49 +479,23 @@
     }
     case field_string:
     {
-        const void *dataptr, *lenptr;
+        const void *dataptr = (const char *)val + field->dataoff;
         const struct atype_info *a;
-        size_t slen;
+        unsigned int slen;
         const struct string_info *string;
 
-        dataptr = (const char *)val + field->dataoff;
-        lenptr = (const char *)val + field->lenoff;
-
         a = field->atype;
         assert(a->type == atype_string || a->type == atype_opaque);
         assert(!(a->type == atype_opaque && field->tag_implicit));
-        assert(field->lentype != 0);
-        assert(field->lentype->type == atype_int || field->lentype->type == atype_uint);
-        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);
-            if (xlen < 0)
-                return EINVAL;
-            if ((size_t) xlen != (asn1_uintmax) xlen)
-                return EINVAL;
-            slen = (size_t) xlen;
-        } else {
-            const struct uint_info *tinfo = field->lentype->tinfo;
-            asn1_uintmax xlen = tinfo->loaduint(lenptr);
-            if ((size_t) xlen != xlen)
-                return EINVAL;
-            slen = (size_t) xlen;
-        }
-
+        retval = get_field_len(val, field, &slen);
+        if (retval)
+            return retval;
         string = a->tinfo;
         dataptr = LOADPTR(dataptr, string);
-        if (slen == SIZE_MAX)
-            /* Error - negative or out of size_t range.  */
-            return EINVAL;
         if (dataptr == NULL && slen != 0)
             return ASN1_MISSING_FIELD;
-        /* Currently string encoders want "unsigned int" for length. */
-        if (slen != (unsigned int)slen)
-            return EINVAL;
         assert(string->enclen != NULL);
-        retval = string->enclen(buf, (unsigned int) slen, dataptr, &length);
+        retval = string->enclen(buf, slen, dataptr, &length);
         if (retval)
             return retval;
         if (a->type == atype_string)
@@ -599,21 +583,20 @@
 }
 
 static asn1_error_code
-encode_sequence_of(asn1buf *buf, int seqlen, const void *val,
+encode_sequence_of(asn1buf *buf, unsigned int seqlen, const void *val,
                    const struct atype_info *eltinfo,
                    unsigned int *retlen)
 {
     asn1_error_code retval;
-    unsigned int sum = 0;
-    int i;
+    unsigned int sum = 0, i;
 
-    for (i = seqlen-1; i >= 0; i--) {
+    for (i = seqlen; i > 0; i--) {
         const void *eltptr;
         unsigned int length;
         const struct atype_info *a = eltinfo;
 
         assert(eltinfo->size != 0);
-        eltptr = (const char *)val + i * eltinfo->size;
+        eltptr = (const char *)val + (i - 1) * eltinfo->size;
         retval = encode_type(buf, eltptr, a, &length, NULL);
         if (retval)
             return retval;



More information about the cvs-krb5 mailing list