case PW_TYPE_OCTETS:
case PW_TYPE_TLV:
{
- size_t max;
+ size_t binlen;
+ size_t hexlen;
- /* Return the number of bytes we would have written */
- len = (inlen * 2) + 2;
- if (freespace <= 1) {
- return len;
- }
+ binlen = inlen;
+ hexlen = (binlen * 2) + 2; /* NOT accounting for trailing NUL */
- *out++ = '0';
- freespace--;
+ /*
+ * If the buffer is too small, put something into
+ * it, and return how much we should have written
+ *
+ * 0 + x + H + H + NUL = 5
+ */
+ if (freespace < 5) {
+ switch (freespace) {
+ case '4':
+ case '3':
+ out[0] = '0';
+ out[1] = 'x';
+ out[2] = '\0';
+ return hexlen;
+
+ case 2:
+ *out = '0';
+ out++;
+ /* FALL-THROUGH */
+
+ case 1:
+ *out = '\0';
+ break;
+
+ case 0:
+ break;
+ }
- if (freespace <= 1) {
- *out = '\0';
- return len;
+ return hexlen;
}
- *out++ = 'x';
- freespace--;
- if (freespace <= 2) {
- *out = '\0';
- return len;
+ /*
+ * The output buffer is at least 5 bytes, we haev
+ * room for '0xHH' plus a trailing NUL byte.
+ */
+ out[0] = '0';
+ out[1] = 'x';
+
+ /*
+ * Get maximum number of bytes we can encode
+ * given freespace, ensuring we account for '0',
+ * 'x', and the trailing NUL in the buffer.
+ *
+ * Note that we can't have "freespace = 0" after
+ * this, as 'freespace' has to be at least 5.
+ */
+ freespace -= 3;
+ freespace /= 2;
+ if (binlen > freespace) {
+ binlen = freespace;
}
- /* Get maximum number of bytes we can encode given freespace */
- max = ((freespace % 2) ? freespace - 1 : freespace - 2) / 2;
- fr_bin2hex(out, data->octets, ((size_t)inlen > max) ? max : (size_t)inlen);
+ fr_bin2hex(out + 2, data->octets, binlen);
+ return hexlen;
}
- return len;
case PW_TYPE_IFID:
a = ifid_ntoa(buf, sizeof(buf), data->ifid);