summaryrefslogtreecommitdiff
path: root/src/openvpn/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/buffer.c')
-rw-r--r--src/openvpn/buffer.c76
1 files changed, 39 insertions, 37 deletions
diff --git a/src/openvpn/buffer.c b/src/openvpn/buffer.c
index a63ce14..f9c76b1 100644
--- a/src/openvpn/buffer.c
+++ b/src/openvpn/buffer.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -1177,7 +1177,7 @@ buffer_list_reset(struct buffer_list *ol)
}
void
-buffer_list_push(struct buffer_list *ol, const unsigned char *str)
+buffer_list_push(struct buffer_list *ol, const char *str)
{
if (str)
{
@@ -1191,7 +1191,7 @@ buffer_list_push(struct buffer_list *ol, const unsigned char *str)
}
struct buffer_entry *
-buffer_list_push_data(struct buffer_list *ol, const uint8_t *data, size_t size)
+buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size)
{
struct buffer_entry *e = NULL;
if (data && (!ol->max_size || ol->size < ol->max_size))
@@ -1231,45 +1231,47 @@ buffer_list_peek(struct buffer_list *ol)
}
void
-buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max, const char *sep)
+buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max_len,
+ const char *sep)
{
- int sep_len = strlen(sep);
+ const int sep_len = strlen(sep);
+ struct buffer_entry *more = bl->head;
+ size_t size = 0;
+ int count = 0;
+ for (count = 0; more; ++count)
+ {
+ size_t extra_len = BLEN(&more->buf) + sep_len;
+ if (size + extra_len > max_len)
+ {
+ break;
+ }
- if (bl->head)
+ size += extra_len;
+ more = more->next;
+ }
+
+ if (count >= 2)
{
- struct buffer_entry *more = bl->head;
- size_t size = 0;
- int count = 0;
- for (count = 0; more && size <= max; ++count)
+ struct buffer_entry *f;
+ ALLOC_OBJ_CLEAR(f, struct buffer_entry);
+ f->buf = alloc_buf(size + 1); /* prevent 0-byte malloc */
+
+ struct buffer_entry *e = bl->head;
+ for (size_t i = 0; e && i < count; ++i)
{
- size += BLEN(&more->buf) + sep_len;
- more = more->next;
+ struct buffer_entry *next = e->next;
+ buf_copy(&f->buf, &e->buf);
+ buf_write(&f->buf, sep, sep_len);
+ free_buf(&e->buf);
+ free(e);
+ e = next;
}
-
- if (count >= 2)
+ bl->head = f;
+ bl->size -= count - 1;
+ f->next = more;
+ if (!more)
{
- int i;
- struct buffer_entry *e = bl->head, *f;
-
- ALLOC_OBJ_CLEAR(f, struct buffer_entry);
- f->buf.data = malloc(size);
- check_malloc_return(f->buf.data);
- f->buf.capacity = size;
- for (i = 0; e && i < count; ++i)
- {
- struct buffer_entry *next = e->next;
- buf_copy(&f->buf, &e->buf);
- buf_write(&f->buf, sep, sep_len);
- free_buf(&e->buf);
- free(e);
- e = next;
- }
- bl->head = f;
- f->next = more;
- if (!more)
- {
- bl->tail = f;
- }
+ bl->tail = f;
}
}
}
@@ -1325,7 +1327,7 @@ buffer_list_file(const char *fn, int max_line_len)
bl = buffer_list_new(0);
while (fgets(line, max_line_len, fp) != NULL)
{
- buffer_list_push(bl, (unsigned char *)line);
+ buffer_list_push(bl, line);
}
free(line);
}