[tpop3d-discuss]Corrupted TOP response with PIPELINING and tpop3d 1.5.3

Chris Lightfoot chris at ex-parrot.com
Wed, 2 Feb 2005 18:28:11 +0000


On Wed, Feb 02, 2005 at 07:22:57PM +0100, Martin Blapp wrote:
> 
> Hi,
> 
> > i'm just trying to reproduce this locally -- can you
> > confirm that this scriptlet should show the problem:
> >
> > perl -MIO::Socket -e '$s = new IO::Socket::INET("localhost:9000");
> 	$s->print("user USERNAME\r\n");
> 	$s->getline();
> 	$s->print("pass PASSWORD\r\n");
> 	$s->getline(); $s->print("LIST\r\n");
> 	for ($i = 1; $i < 2000; ++$i) {
> 		$j=1 + $i%500;
> 		$s->print("top $j 0\r\n");
> 	 }
> 	$s->print("quit\r\n");
> 	while (defined($_ = $s->getline())) { print $_; }'
> >
> > (replace USERNAME and PASSWORD as appropriate)
> 
> Why modulo $i%500  Just use $i ... its easier to debug afterwords.

oh -- the test mailbox only had about 500 mails in it.

> Yes it should trigger the problem.

ok... i can't reproduce it here, so it must be timing
dependent :(

that said there are definitely problems in the buffering
code. Can you try the following patch:

diff -u -r1.7 buffer.c
--- buffer.c    6 Nov 2003 01:19:27 -0000       1.7
+++ buffer.c    2 Feb 2005 18:24:22 -0000
@@ -208,10 +224,18 @@
 
 /* buffer_get_push_ptr BUFFER LEN
  * Return a pointer to part of BUFFER to which new data can be written. On
- * return, LEN indicates how many contiguous bytes may be written. */
+ * return, *LEN indicates how many contiguous bytes may be written. */
 char *buffer_get_push_ptr(buffer B, size_t *len) {
     assert(B);
-    *len = B->len - B->put;
+
+    if (B->put >= B->get) {
+        *len = B->len - B->put;
+        if (B->get == 0)
+            --*len;
+    } else if (B->put < B->get) {
+        *len = B->get - B->put - 1;
+    }
+    
     return B->buf + B->put;
 }
 

and tell me if it helps?

-- 
``In these troubled times, perhaps we all need reminding that when we all
  work together and really put our minds to something, we still can't achieve
  the impossible.'' (from Need To Know)