| 34 | #define av_bprint_is_allocated(buf) ((buf)->str != (buf)->reserved_internal_buffer) |
| 35 | |
| 36 | static int av_bprint_alloc(AVBPrint *buf, unsigned room) |
| 37 | { |
| 38 | char *old_str, *new_str; |
| 39 | unsigned min_size, new_size; |
| 40 | |
| 41 | if (buf->size == buf->size_max) |
| 42 | return AVERROR(EIO); |
| 43 | if (!av_bprint_is_complete(buf)) |
| 44 | return AVERROR_INVALIDDATA; /* it is already truncated anyway */ |
| 45 | min_size = buf->len + 1 + FFMIN(UINT_MAX - buf->len - 1, room); |
| 46 | new_size = buf->size > buf->size_max / 2 ? buf->size_max : buf->size * 2; |
| 47 | if (new_size < min_size) |
| 48 | new_size = FFMIN(buf->size_max, min_size); |
| 49 | old_str = av_bprint_is_allocated(buf) ? buf->str : NULL; |
| 50 | new_str = av_realloc(old_str, new_size); |
| 51 | if (!new_str) |
| 52 | return AVERROR(ENOMEM); |
| 53 | if (!old_str) |
| 54 | memcpy(new_str, buf->str, buf->len + 1); |
| 55 | buf->str = new_str; |
| 56 | buf->size = new_size; |
| 57 | return 0; |
| 58 | } |
| 59 | |
| 60 | static void av_bprint_grow(AVBPrint *buf, unsigned extra_len) |
| 61 | { |
no test coverage detected