]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Ensure da is parented from VP, not ctx
authorAlan T. DeKok <aland@freeradius.org>
Fri, 15 Apr 2016 14:54:02 +0000 (10:54 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 15 Apr 2016 14:56:27 +0000 (10:56 -0400)
src/lib/pair.c

index f8631ef8b0f77416d22b7969d047361a60c85b1a..7deccdbb80468fdfcbc3a5b701d2dbebf764a4c9 100644 (file)
@@ -1288,37 +1288,6 @@ finish:
 }
 
 
-static VALUE_PAIR *fr_pair_from_octets(TALLOC_CTX *ctx, VALUE_PAIR *vp, DICT_ATTR const *da)
-{
-       ssize_t len;
-       VALUE_PAIR *vp2;
-
-       len = data2vp(ctx, NULL, NULL, NULL, da,
-                     vp->vp_octets, vp->vp_length, vp->vp_length,
-                     &vp2);
-       if (len <= 0) return vp; /* it's really unknown */
-
-       if (vp2->da->flags.is_unknown) {
-               fr_pair_list_free(&vp2);
-               return vp;
-       }
-
-       /*
-        *      Didn't parse all of it.  Return the "unknown" one.
-        *
-        *      FIXME: it COULD have parsed 2 attributes and
-        *      then not the third, so returning 2 "knowns"
-        *      and 1 "unknown" is likely preferable.
-        */
-       if ((size_t) len < vp->vp_length) {
-               fr_pair_list_free(&vp2);
-               return vp;
-       }
-
-       fr_pair_list_free(&vp);
-       return vp2;
-}
-
 /** Create a valuepair from an ASCII attribute and value
  *
  * Where the attribute name is in the form:
@@ -1337,44 +1306,47 @@ static VALUE_PAIR *fr_pair_make_unknown(TALLOC_CTX *ctx,
                                        char const *attribute, char const *value,
                                        FR_TOKEN op)
 {
-       VALUE_PAIR      *vp;
+       VALUE_PAIR      *vp, *vp2;
        DICT_ATTR const *da;
 
        uint8_t         *data;
        size_t          size;
+       ssize_t         len;
+
+       vp = fr_pair_alloc(ctx);
+       if (!vp) return NULL;
 
-       da = dict_unknown_afrom_str(ctx, attribute);
-       if (!da) return NULL;
+       da = dict_unknown_afrom_str(vp, attribute);
+       if (!da) {
+               talloc_free(vp);
+               return NULL;
+       }
+
+       /*
+        *      No value.  Nothing more to do.
+        */
+       if (!value) return vp;
 
        /*
         *      Unknown attributes MUST be of type 'octets'
         */
-       if (value && (strncasecmp(value, "0x", 2) != 0)) {
+       if (strncasecmp(value, "0x", 2) != 0) {
                fr_strerror_printf("Unknown attribute \"%s\" requires a hex "
                                   "string, not \"%s\"", attribute, value);
-
-               dict_attr_free(&da);
+               talloc_free(vp);
                return NULL;
        }
 
        /*
-        *      We've now parsed the attribute properly, Let's create
-        *      it.  This next stop also looks the attribute up in the
-        *      dictionary, and creates the appropriate type for it.
+        *      Convert the hex data to binary.
         */
-       vp = fr_pair_afrom_da(ctx, da);
-       if (!vp) {
-               dict_attr_free(&da);
-               return NULL;
-       }
-
-       vp->op = (op == 0) ? T_OP_EQ : op;
-
-       if (!value) return vp;
-
        size = strlen(value + 2);
+
        vp->vp_length = size >> 1;
-       data = talloc_array(vp, uint8_t, vp->vp_length);
+       vp->vp_octets = data = talloc_array(vp, uint8_t, vp->vp_length);
+       vp->type = VT_DATA;
+       vp->op = (op == 0) ? T_OP_EQ : op;
+       vp->da = da;
 
        if (fr_hex2bin(data, vp->vp_length, value + 2, size) != vp->vp_length) {
                fr_strerror_printf("Invalid hex string");
@@ -1382,21 +1354,43 @@ static VALUE_PAIR *fr_pair_make_unknown(TALLOC_CTX *ctx,
                return NULL;
        }
 
-       vp->vp_octets = data;
-       vp->type = VT_DATA;
+       /*
+        *      It's still unknown, return it as-is.
+        */
+       da = dict_attrbyvalue(vp->da->attr, vp->da->vendor);
+       if (!da) return vp;
 
        /*
-        *      We were asked to parse "Attr-26 = 0xabcdef"
+        *      It MIGHT be known.  See if we can decode the raw data
+        *      into a valid attribute.
+        */
+       len = data2vp(ctx, NULL, NULL, NULL, da,
+                     vp->vp_octets, vp->vp_length, vp->vp_length,
+                     &vp2);
+       if (len <= 0) return vp;
+
+       /*
+        *      It's still unknown.  Return the original VP.
+        */
+       if (vp2->da->flags.is_unknown) {
+               fr_pair_list_free(&vp2);
+               return vp;
+       }
+
+       /*
+        *      Didn't parse all of it.  Return the "unknown" one.
         *
-        *      If we have a dictionary entry for it, try to
-        *      parse it as raw data.
+        *      FIXME: it COULD have parsed 2 attributes and
+        *      then not the third, so returning 2 "knowns"
+        *      and 1 "unknown" is likely preferable.
         */
-       da = dict_attrbyvalue(vp->da->attr, vp->da->vendor);
-       if (da) {
-               return fr_pair_from_octets(ctx, vp, da);
+       if ((size_t) len < vp->vp_length) {
+               fr_pair_list_free(&vp2);
+               return vp;
        }
 
-       return vp;
+       fr_pair_list_free(&vp);
+       return vp2;
 }