[tpop3d-discuss] [PATCH] Corrupted TOP response with PIPELINING
and tpop3d 1.5.3
Martin Blapp
mb at imp.ch
Wed, 2 Feb 2005 18:09:22 +0100 (CET)
Hi Chris,
>um. The only places buffer_push_bytes is called,
>buffer_expand has been called immediately before it. I
>*think* -- I haven't had time to look in detail today --
>that the problem is in buffer_get_push_ptr -- it can cause
>too much data to be read in the case where the read
>pointer is still at the beginning of the buffer.
buffer_expand does not expand at all if readpos and writepos
are 0. You overwrite then the same buffer over and again without
reading anything.
Uhm, I forgot something. The previous patch was DOS'able. A upper
limit of 4MB should be enough to satisfy anyone. Of course one
could argue that we should output an error then and abort everything.
Martin
--- buffer.c.orig Thu Nov 6 02:19:27 2003
+++ buffer.c Wed Feb 2 18:01:41 2005
@@ -220,4 +220,20 @@
* a location returned by buffer_get_push_ptr. */
void buffer_push_bytes(buffer B, const size_t num) {
B->put = (B->put + num) % B->len;
+ /* check if we reached the readpos and expand buffer if necessary*/
+ if(B->len*2 <= MAXEXPANDBUF && num && (B->put == B->get)) {
+ char* newbuf;
+ newbuf = xmalloc(B->len*2);
+ if(B->put)
+ bcopy(B->buf+B->put, newbuf, B->len - B->put);
+ if(B->put)
+ bcopy(B->buf, newbuf+B->put, B->put);
+ else
+ bcopy(B->buf, newbuf+B->put, B->len);
+ B->get = 0;
+ B->put = B->len;
+ B->len = B->len*2;
+ xfree(B->buf);
+ B->buf = newbuf;
+ }
}
--- buffer.h.orig Wed Feb 2 18:00:03 2005
+++ buffer.h Wed Feb 2 18:00:06 2005
@@ -22,6 +22,7 @@
* Return the number of bytes of data available to consume from BUFFER. This
* is a macro which may evaluate BUFFER more than once. */
#define buffer_available(B) ((size_t)(((B)->put + (B)->len - (B)->get) %
(B)->len))
+#define MAXEXPANDBUF 4194304
/* buffer.c */
buffer buffer_new(const size_t len);