if (_slen < 0) return _slen; \
} while (0)
+/** Generic wrapper to return an error and an offset from encoding.
+ *
+ * Some encoders return PAIR_ENCODE_FATAL_ERROR. Substracting an
+ * offset from that values means it wraps be be a positive number
+ * near INT64_MAX. This macro ensures that doesn't happen.
+ */
+#define FR_DBUFF_ERROR_OFFSET(_slen, _offset) ((_slen < INT32_MAX) ? _slen : _slen - (ssize_t) _offset)
+
/** @name Initialisers
* @{
*/
}
slen = fr_cbor_decode_pair(ctx, out, &dbuff, parent, false);
- if (slen <= 0) return slen - fr_dbuff_used(&dbuff);
+ if (slen <= 0) return FR_DBUFF_ERROR_OFFSET(slen, fr_dbuff_used(&dbuff));
} while (true);
return fr_dbuff_used(&dbuff);
ssize_t slen;
slen = fr_cbor_encode_pair(&work_dbuff, vp);
- if (slen <= 0) return slen - fr_dbuff_used(&work_dbuff);
+ if (slen <= 0) return FR_DBUFF_ERROR_OFFSET(slen, fr_dbuff_used(&work_dbuff));
}
FR_DBUFF_IN_BYTES_RETURN(&work_dbuff, (uint8_t) 0xff); /* end of indefinite array */
fr_pair_dcursor_iter_init(&cursor, vps, fr_dhcpv6_next_encodable, dict_dhcpv6);
while ((fr_dbuff_extend(&frame_dbuff) > 0) && (fr_dcursor_current(&cursor) != NULL)) {
slen = fr_dhcpv6_encode_option(&frame_dbuff, &cursor, &packet_ctx);
- if (slen < 0) return slen - fr_dbuff_used(&frame_dbuff);
+ if (slen < 0) return FR_DBUFF_ERROR_OFFSET(slen, fr_dbuff_used(&frame_dbuff));
}
return fr_dbuff_set(dbuff, &frame_dbuff);
* Encode questions
*/
slen = encode_record(&work_dbuff, &da_stack, vps, attr_dns_question, packet_ctx, packet + 4);
- if (slen < 0) return slen - fr_dbuff_used(&work_dbuff);
+ if (slen < 0) return FR_DBUFF_ERROR_OFFSET(slen, fr_dbuff_used(&work_dbuff));
/*
* Encode answers
*/
slen = encode_record(&work_dbuff, &da_stack, vps, attr_dns_rr, packet_ctx, packet + 6);
- if (slen < 0) return slen - fr_dbuff_used(&work_dbuff);
+ if (slen < 0) return FR_DBUFF_ERROR_OFFSET(slen, fr_dbuff_used(&work_dbuff));
/*
* Encode NS records
*/
slen = encode_record(&work_dbuff, &da_stack, vps, attr_dns_ns, packet_ctx, packet + 8);
- if (slen < 0) return slen - fr_dbuff_used(&work_dbuff);
+ if (slen < 0) return FR_DBUFF_ERROR_OFFSET(slen, fr_dbuff_used(&work_dbuff));
/*
* Encode additional records
*/
slen = encode_record(&work_dbuff, &da_stack, vps, attr_dns_ar, packet_ctx, packet + 10);
- if (slen < 0) return slen - fr_dbuff_used(&work_dbuff);
+ if (slen < 0) return FR_DBUFF_ERROR_OFFSET(slen, fr_dbuff_used(&work_dbuff));
return fr_dbuff_set(dbuff, &work_dbuff);
}
if (child_argc > (arg_cnt - i)) child_argc = arg_cnt = i;
slen = tacacs_encode_body_arg_n(&work_dbuff, child_argc, &arg_len[i], &vp->vp_group, vp->da);
- if (slen < 0) return slen - fr_dbuff_used(&work_dbuff);
+ if (slen < 0) return FR_DBUFF_ERROR_OFFSET(slen, fr_dbuff_used(&work_dbuff));
i += child_argc;
continue;