out[0] = '\0';
if (!vp) return 0;
+ if ((vp->type & PW_FLAG_LONG) != 0) goto do_tlv;
+
switch (vp->type) {
case PW_TYPE_STRING:
if ((delimitst == 1) && vp->flags.has_tag) {
break;
case PW_TYPE_TLV:
+ do_tlv:
if (outlen <= (2 * (vp->length + 1))) return 0;
strcpy(buf, "0x");
bufsize -= len;
}
- len = vp_print_attr_oid(p, bufsize , attr, dv_type);
+ vp_print_attr_oid(p, bufsize , attr, dv_type);
return buffer;
}
data = vp->vp_octets;
len = vp->length;
+ /*
+ * Short-circuit it for long attributes. They can't be
+ * encrypted, tagged, etc.
+ */
+ if ((vp->type & PW_FLAG_LONG) != 0) goto do_tlv;
+
switch(vp->type) {
case PW_TYPE_STRING:
case PW_TYPE_OCTETS:
}
case PW_TYPE_TLV:
+ do_tlv:
data = vp->vp_tlv;
if (!data) {
fr_strerror_printf("ERROR: Cannot encode NULL TLV");
vp->length = length;
/*
- * If the data is too large, mark it as a "TLV".
+ * If it's short, put it into the array. If it's too
+ * long, flag it as such, and put it somewhere else;
*/
if (length <= sizeof(vp->vp_octets)) {
memcpy(vp->vp_octets, data, length);
} else {
- vp->type = PW_TYPE_TLV;
+ vp->type |= PW_FLAG_LONG;
vp->vp_tlv = malloc(length);
if (!vp->vp_tlv) {
pairfree(&vp);
/* raw octets: 0x01020304... */
case PW_TYPE_OCTETS:
if (strncasecmp(value, "0x", 2) == 0) {
+ size_t size;
uint8_t *us;
+
cp = value + 2;
us = vp->vp_octets;
vp->length = 0;
-
/*
- * There is only one character,
- * die.
+ * Invalid.
*/
- if ((strlen(cp) & 0x01) != 0) {
+ size = strlen(cp);
+ if ((size & 0x01) != 0) {
fr_strerror_printf("Hex string is not an even length string.");
return NULL;
}
-
- while (*cp &&
- (vp->length < MAX_STRING_LEN)) {
- unsigned int tmp;
-
- if (sscanf(cp, "%02x", &tmp) != 1) {
- fr_strerror_printf("Non-hex characters at %c%c", cp[0], cp[1]);
+ vp->length = size >> 1;
+ if (size > 2*sizeof(vp->vp_octets)) {
+ vp->type |= PW_FLAG_LONG;
+ us = vp->vp_tlv = malloc(vp->length);
+ if (!us) {
+ fr_strerror_printf("Out of memory.");
return NULL;
}
+ }
- cp += 2;
- *(us++) = tmp;
- vp->length++;
+ if (fr_hex2bin(cp, us,
+ vp->length) != vp->length) {
+ fr_strerror_printf("Invalid hex data");
+ return NULL;
}
}
break;
unsigned int dv_type = 1;
size_t size;
const char *p = attribute;
+ void *data;
char *q;
VALUE_PAIR *vp;
DICT_VENDOR *dv;
if (!value) return vp;
size = strlen(value + 2);
+ data = vp->vp_octets;
/*
* We may be reading something like Attr-5. i.e.
case PW_TYPE_ABINARY:
vp->length = size >> 1;
if (vp->length > sizeof(vp->vp_octets)) {
- vp->length = sizeof(vp->vp_octets);
+ vp->vp_tlv = malloc(vp->length);
+ if (!vp->vp_tlv) {
+ fr_strerror_printf("Out of memory");
+ free(vp);
+ return NULL;
+ }
+ data = vp->vp_tlv;
+ vp->type |= PW_FLAG_LONG;
}
break;
vp->length = size >> 1;
memset(&vp->vp_strvalue, 0, sizeof(vp->vp_strvalue));
if (vp->length >= sizeof(vp->vp_strvalue)) {
- vp->length = sizeof(vp->vp_strvalue) - 1;
+ vp->vp_tlv = malloc(vp->length);
+ if (!vp->vp_tlv) {
+ fr_strerror_printf("Out of memory");
+ free(vp);
+ return NULL;
+ }
+ data = vp->vp_tlv;
+ vp->type |= PW_FLAG_LONG;
}
break;
}
- if (fr_hex2bin(value + 2, vp->vp_octets, size) != vp->length) {
+ if (fr_hex2bin(value + 2, data, size) != vp->length) {
fr_strerror_printf("Invalid hex string");
free(vp);
return NULL;