]> diplodocus.org Git - nmh/commitdiff
Move the read buffer shuffling to BEFORE where we call the network
authorKen Hornstein <kenh@pobox.com>
Sun, 2 Oct 2016 05:47:15 +0000 (01:47 -0400)
committerKen Hornstein <kenh@pobox.com>
Sun, 2 Oct 2016 05:47:15 +0000 (01:47 -0400)
read routines; otherwise we can end up calling the lower layers with
a length of zero, which messes everything up.

Also make sure we reshuffle our pointers around if that happens.

sbr/netsec.c

index 5f822b1..6d19fcc 100644 (file)
@@ -550,10 +550,38 @@ retry:
         */
     }
 
+    /*
+     * Some explanation:
+     *
+     * startoffset is the offset from the beginning of the input buffer
+     * of data that has is in our input buffer, but has not yet been
+     * consumed.  This can be non-zero, if, functions like netsec_readline()
+     * leave leftover data.
+     *
+     * remaining is the remaining amount of unconsumed data in the input
+     * buffer.
+     *
+     * end is a pointer to the end of the valid data + 1; it's where
+     * the next read should go.
+     */
+
     startoffset = nsc->ns_inptr - nsc->ns_inbuffer;
     remaining = nsc->ns_inbufsize - (startoffset + nsc->ns_inbuflen);
     end = nsc->ns_inptr + nsc->ns_inbuflen;
 
+    /*
+     * If we're past the halfway point in our read buffers, shuffle everything
+     * back to the beginning.
+     */
+
+    if (startoffset > nsc->ns_inbufsize / 2) {
+       memmove(nsc->ns_inbuffer, nsc->ns_inptr, nsc->ns_inbuflen);
+       nsc->ns_inptr = nsc->ns_inbuffer;
+       startoffset = 0;
+       remaining = nsc->ns_inbufsize - nsc->ns_inbuflen;
+       end = nsc->ns_inptr + nsc->ns_inbuflen;
+    }
+
     /*
      * If we are using TLS, then just read via the BIO.  But we still
      * use our local buffer.
@@ -679,16 +707,6 @@ retry:
 #endif /* CYRUS_SASL */
        nsc->ns_inbuflen += rc;
 
-    /*
-     * If we're past the halfway point in our read buffers, shuffle everything
-     * back to the beginning.
-     */
-
-    if (startoffset > nsc->ns_inbufsize / 2) {
-       memmove(nsc->ns_inbuffer, nsc->ns_inptr, nsc->ns_inbuflen);
-       nsc->ns_inptr = nsc->ns_inbuffer;
-    }
-
     return OK;
 }