summaryrefslogtreecommitdiff
path: root/usr/src/cmd/ssh/libssh/common/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/ssh/libssh/common/buffer.c')
-rw-r--r--usr/src/cmd/ssh/libssh/common/buffer.c64
1 files changed, 50 insertions, 14 deletions
diff --git a/usr/src/cmd/ssh/libssh/common/buffer.c b/usr/src/cmd/ssh/libssh/common/buffer.c
index 9d95851d68..45d6860157 100644
--- a/usr/src/cmd/ssh/libssh/common/buffer.c
+++ b/usr/src/cmd/ssh/libssh/common/buffer.c
@@ -11,15 +11,20 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-#include "includes.h"
-RCSID("$OpenBSD: buffer.c,v 1.23 2005/03/14 11:46:56 markus Exp $");
+/* $OpenBSD: buffer.c,v 1.31 2006/08/03 03:34:41 deraadt Exp $ */
#pragma ident "%Z%%M% %I% %E% SMI"
+#include "includes.h"
+
#include "xmalloc.h"
#include "buffer.h"
#include "log.h"
+#define BUFFER_MAX_CHUNK 0x100000
+#define BUFFER_MAX_LEN 0xa00000
+#define BUFFER_ALLOCSZ 0x008000
+
/* Initializes the buffer structure. */
void
@@ -68,6 +73,23 @@ buffer_append(Buffer *buffer, const void *data, u_int len)
memcpy(p, data, len);
}
+static int
+buffer_compact(Buffer *buffer)
+{
+ /*
+ * If the buffer is quite empty, but all data is at the end, move the
+ * data to the beginning.
+ */
+ if (buffer->offset > MIN(buffer->alloc, BUFFER_MAX_CHUNK)) {
+ memmove(buffer->buf, buffer->buf + buffer->offset,
+ buffer->end - buffer->offset);
+ buffer->end -= buffer->offset;
+ buffer->offset = 0;
+ return (1);
+ }
+ return (0);
+}
+
/*
* Appends space to the buffer, expanding the buffer if necessary. This does
* not actually copy the data into the buffer, but instead returns a pointer
@@ -95,20 +117,13 @@ restart:
buffer->end += len;
return p;
}
- /*
- * If the buffer is quite empty, but all data is at the end, move the
- * data to the beginning and retry.
- */
- if (buffer->offset > MIN(buffer->alloc, BUFFER_MAX_CHUNK)) {
- memmove(buffer->buf, buffer->buf + buffer->offset,
- buffer->end - buffer->offset);
- buffer->end -= buffer->offset;
- buffer->offset = 0;
+
+ /* Compact data back to the start of the buffer if necessary */
+ if (buffer_compact(buffer))
goto restart;
- }
+
/* Increase the size of the buffer and retry. */
-
- newlen = buffer->alloc + len + 32768;
+ newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
if (newlen > BUFFER_MAX_LEN)
fatal("buffer_append_space: alloc %u not supported",
newlen);
@@ -118,6 +133,27 @@ restart:
/* NOTREACHED */
}
+/*
+ * Check whether an allocation of 'len' will fit in the buffer
+ * This must follow the same math as buffer_append_space
+ */
+int
+buffer_check_alloc(Buffer *buffer, u_int len)
+{
+ if (buffer->offset == buffer->end) {
+ buffer->offset = 0;
+ buffer->end = 0;
+ }
+ restart:
+ if (buffer->end + len < buffer->alloc)
+ return (1);
+ if (buffer_compact(buffer))
+ goto restart;
+ if (roundup(buffer->alloc + len, BUFFER_ALLOCSZ) <= BUFFER_MAX_LEN)
+ return (1);
+ return (0);
+}
+
/* Returns the number of bytes of data in the buffer. */
u_int