summaryrefslogtreecommitdiffstats
path: root/src/bytearray.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytearray.c')
-rw-r--r--src/bytearray.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/src/bytearray.c b/src/bytearray.c
index 89c5ec7..19303e0 100644
--- a/src/bytearray.c
+++ b/src/bytearray.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
+#include <stdint.h>
#include "bytearray.h"
#define PAGE_SIZE 4096
@@ -26,8 +27,24 @@
bytearray_t *byte_array_new(size_t initial)
{
bytearray_t *a = (bytearray_t*)malloc(sizeof(bytearray_t));
- a->capacity = (initial > PAGE_SIZE) ? (initial+(PAGE_SIZE-1)) & (~(PAGE_SIZE-1)) : PAGE_SIZE;
+ if (!a) {
+ return NULL;
+ }
+ if (initial > PAGE_SIZE) {
+ if (initial > SIZE_MAX - (PAGE_SIZE-1)) {
+ /* rounding up to the page size would overflow */
+ free(a);
+ return NULL;
+ }
+ a->capacity = (initial+(PAGE_SIZE-1)) & (~(PAGE_SIZE-1));
+ } else {
+ a->capacity = PAGE_SIZE;
+ }
a->data = malloc(a->capacity);
+ if (!a->data) {
+ free(a);
+ return NULL;
+ }
a->len = 0;
a->stream = NULL;
return a;
@@ -36,6 +53,9 @@ bytearray_t *byte_array_new(size_t initial)
bytearray_t *byte_array_new_for_stream(FILE *stream)
{
bytearray_t *a = (bytearray_t*)malloc(sizeof(bytearray_t));
+ if (!a) {
+ return NULL;
+ }
a->capacity = (size_t)-1;
a->data = NULL;
a->len = 0;
@@ -57,9 +77,15 @@ void byte_array_grow(bytearray_t *ba, size_t amount)
if (ba->stream || !ba->data) {
return;
}
- size_t increase = (amount > PAGE_SIZE) ? (amount+(PAGE_SIZE-1)) & (~(PAGE_SIZE-1)) : PAGE_SIZE;
- if (increase < amount || ba->capacity + increase < ba->capacity) {
- /* size overflow */
+ size_t increase;
+ if (amount > PAGE_SIZE) {
+ /* round up to the page size, guarding against integer overflow */
+ increase = (amount <= SIZE_MAX - (PAGE_SIZE-1)) ? ((amount+(PAGE_SIZE-1)) & (~(PAGE_SIZE-1))) : 0;
+ } else {
+ increase = PAGE_SIZE;
+ }
+ if (increase == 0 || increase > SIZE_MAX - ba->capacity) {
+ /* integer overflow */
free(ba->data);
ba->data = NULL;
ba->len = 0;
@@ -101,6 +127,10 @@ void byte_array_append(bytearray_t *ba, void *buf, size_t len)
#endif
}
} else {
+ if (len > SIZE_MAX - ba->len) {
+ /* integer overflow when computing the new total length */
+ return;
+ }
size_t remaining = ba->capacity-ba->len;
if (len > remaining) {
size_t needed = len - remaining;