26 RCSID(
"$Id: de5ce998e69f5ff8628c640cd21f668e7fc0fd1a $")
28 #include <freeradius-devel/util/dbuff.h>
29 #include <freeradius-devel/util/syserror.h>
31 #if defined(STATIC_ANALYZER) || !defined(NDEBUG)
32 # define CHECK_DBUFF_INIT(_sbuff) do { if (!(_sbuff)->extend && (unlikely(!(_sbuff)->buff) || unlikely(!(_sbuff)->start) || unlikely(!(_sbuff)->end) || unlikely(!(_sbuff)->p))) return 0; } while (0)
34 # define CHECK_DBUFF_INIT(_sbuff)
41 #define FR_DBUFF_MOVE_DEF(_out_type, _in_type) \
42 size_t _fr_dbuff_move_##_in_type##_to_##_out_type(fr_##_out_type##_t *out, fr_##_in_type##_t *in, size_t len) \
44 size_t ext_len, to_copy, remaining = len; \
45 while (remaining > 0) { \
46 to_copy = remaining; \
47 ext_len = fr_dbuff_extend_lowat(NULL, in, to_copy); \
48 if (ext_len < to_copy) to_copy = ext_len; \
49 ext_len = fr_dbuff_extend_lowat(NULL, out, to_copy); \
50 if (ext_len < to_copy) to_copy = ext_len; \
51 if (to_copy == 0) break; \
52 to_copy = _fr_dbuff_safecpy(fr_dbuff_current(out), fr_dbuff_end(out), \
53 fr_dbuff_current(in), fr_dbuff_current(in) + to_copy); \
54 fr_dbuff_advance(out, (size_t)fr_dbuff_advance(in, to_copy)); \
55 remaining -= to_copy; \
57 return len - remaining; \
66 static inline CC_HINT(always_inline)
size_t min(
size_t x,
size_t y)
84 old_buff = dbuff->buff;
92 for (dbuff_i = dbuff; dbuff_i; dbuff_i = dbuff_i->parent) {
95 dbuff_i->buff = new_buff;
96 dbuff_i->start = new_buff +
min(new_len, dbuff_i->start - old_buff);
97 dbuff_i->end = dbuff_i->buff + new_len;
98 dbuff_i->
p = new_buff +
min(new_len, dbuff_i->
p - old_buff);
100 for (m_i = dbuff_i->m; m_i; m_i = m_i->next) m_i->p = new_buff +
min(new_len, m_i->p - old_buff);
120 size_t max_shift = shift;
133 for (dbuff_i = dbuff; dbuff_i; dbuff_i = dbuff_i->parent) {
136 max_shift =
min(max_shift, dbuff_i->
p -
buff);
137 if (!max_shift)
return 0;
139 for (m_i = dbuff_i->m; m_i; m_i = m_i->next) {
140 max_shift =
min(max_shift, m_i->p -
buff);
141 if (!max_shift)
return 0;
153 for (dbuff_i = dbuff; dbuff_i; dbuff_i = dbuff_i->parent) {
155 uint8_t *start = dbuff_i->start;
157 dbuff_i->start -=
min(max_shift, dbuff_i->start -
buff);
158 dbuff_i->
p -= max_shift;
159 dbuff_i->end -= max_shift;
160 dbuff_i->shifted += (max_shift - (start - dbuff_i->start));
161 for (m_i = dbuff_i->m; m_i; m_i = m_i->next) m_i->
p -= max_shift;
167 if ((
buff + max_shift) < end) memmove(
buff,
buff + max_shift, end - (
buff + max_shift));
178 size_t available, total_read;
179 fr_dbuff_uctx_fd_t *fctx;
185 if (extension == SIZE_MAX) extension = 0;
187 total_read = dbuff->shifted + (dbuff->end - dbuff->buff);
188 if (total_read >= fctx->max) {
203 available =
min(fctx->buff_end - dbuff->end, fctx->max - total_read);
204 if (available < extension) {
209 bytes_read = read(fctx->fd, dbuff->end, available);
213 if (bytes_read < 0) {
219 dbuff->end += bytes_read;
237 fr_dbuff_uctx_talloc_t *tctx = dbuff->uctx;
238 size_t clen, nlen, elen = extension;
243 clen = dbuff->buff ? talloc_array_length(dbuff->buff) : 0;
251 if ((clen + elen) < tctx->init) {
252 elen = tctx->init - clen;
257 }
else if (elen < clen){
265 if (tctx->max && ((clen + elen) > tctx->max)) {
266 elen = tctx->max - clen;
269 "%zu bytes, max is %zu bytes",
270 extension, clen + extension, tctx->max);
276 new_buff = talloc_realloc(tctx->ctx, dbuff->buff,
uint8_t, nlen);
299 size_t clen = 0, nlen = 0;
301 fr_dbuff_uctx_talloc_t *tctx = dbuff->uctx;
305 if (dbuff->buff) clen = talloc_array_length(dbuff->buff);
307 if (len != SIZE_MAX) {
309 }
else if (dbuff->buff){
310 nlen += (dbuff->
p - dbuff->start);
314 new_buff = talloc_realloc(tctx->ctx, dbuff->buff,
uint8_t, nlen);
334 fr_dbuff_uctx_talloc_t *tctx = dbuff->uctx;
343 new_buff = talloc_realloc(tctx->ctx, dbuff->buff,
uint8_t, tctx->init);
346 talloc_array_length(dbuff->buff), tctx->init);
349 dbuff->buff = new_buff;
int fr_dbuff_reset_talloc(fr_dbuff_t *dbuff)
Reset a talloced buffer to its initial length, clearing any data stored.
int fr_dbuff_trim_talloc(fr_dbuff_t *dbuff, size_t len)
Trim a talloced dbuff to the minimum length required to represent the contained string.
#define CHECK_DBUFF_INIT(_sbuff)
size_t _fr_dbuff_extend_fd(fr_dbuff_t *dbuff, size_t extension)
Refresh the buffer with more data from the file.
void fr_dbuff_update(fr_dbuff_t *dbuff, uint8_t *new_buff, size_t new_len)
Update all markers and pointers in the set of dbuffs to point to new_buff.
#define FR_DBUFF_MOVE_DEF(_out_type, _in_type)
size_t fr_dbuff_shift(fr_dbuff_t *dbuff, size_t shift)
Shift the contents of the dbuff, returning the number of bytes we managed to shift.
#define fr_dbuff_used(_dbuff_or_marker)
Return the number of bytes remaining between the start of the dbuff or marker and the current positio...
struct fr_dbuff_marker_s fr_dbuff_marker_t
A position marker associated with a dbuff.
#define fr_dbuff_set_to_start(_dbuff_or_marker)
Reset the 'current' position of the dbuff or marker to the 'start' of the buffer.
size_t _fr_dbuff_extend_talloc(fr_dbuff_t *dbuff, size_t extension)
Reallocate the current buffer.
static size_t min(size_t x, size_t y)
static char buff[sizeof("18446744073709551615")+3]
PRIVATE void strings(struct DATA *p, char *tmp)
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.