Fix BIO_f_buffer().
authorBodo Möller <bodo@openssl.org>
Fri, 2 Dec 2011 12:23:57 +0000 (12:23 +0000)
committerBodo Möller <bodo@openssl.org>
Fri, 2 Dec 2011 12:23:57 +0000 (12:23 +0000)
Submitted by: Adam Langley
Reviewed by: Bodo Moeller

CHANGES
crypto/bio/bf_buff.c
crypto/bio/bio.h

diff --git a/CHANGES b/CHANGES
index 958362a449d14e4e5d2b265376181659a8536207..e03f7477cdbc867bf456b6ceddaae595f0281ce2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,10 @@
 
  Changes between 0.9.8r and 0.9.8s [xx XXX xxxx]
 
+  *) Fix the BIO_f_buffer() implementation (which was mixing different
+     interpretations of the '..._len' fields).
+     [Adam Langley (Google)]
+
   *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than
      BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent
      threads won't reuse the same blinding coefficients.
index c1fd75aaad80f071c0f2fce330c08d95b6bd4ddd..4b5a132d8a18320dab2f78ea7f41378d4456f7c0 100644 (file)
@@ -209,7 +209,7 @@ start:
        /* add to buffer and return */
        if (i >= inl)
                {
-               memcpy(&(ctx->obuf[ctx->obuf_len]),in,inl);
+               memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,inl);
                ctx->obuf_len+=inl;
                return(num+inl);
                }
@@ -219,7 +219,7 @@ start:
                {
                if (i > 0) /* lets fill it up if we can */
                        {
-                       memcpy(&(ctx->obuf[ctx->obuf_len]),in,i);
+                       memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,i);
                        in+=i;
                        inl-=i;
                        num+=i;
@@ -294,9 +294,9 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
        case BIO_C_GET_BUFF_NUM_LINES:
                ret=0;
                p1=ctx->ibuf;
-               for (i=ctx->ibuf_off; i<ctx->ibuf_len; i++)
+               for (i=0; i<ctx->ibuf_len; i++)
                        {
-                       if (p1[i] == '\n') ret++;
+                       if (p1[ctx->ibuf_off + i] == '\n') ret++;
                        }
                break;
        case BIO_CTRL_WPENDING:
@@ -399,17 +399,18 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
                for (;;)
                        {
                        BIO_clear_retry_flags(b);
-                       if (ctx->obuf_len > ctx->obuf_off)
+                       if (ctx->obuf_len > 0)
                                {
                                r=BIO_write(b->next_bio,
                                        &(ctx->obuf[ctx->obuf_off]),
-                                       ctx->obuf_len-ctx->obuf_off);
+                                       ctx->obuf_len);
 #if 0
-fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len-ctx->obuf_off,r);
+fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len,r);
 #endif
                                BIO_copy_next_retry(b);
                                if (r <= 0) return((long)r);
                                ctx->obuf_off+=r;
+                               ctx->obuf_len-=r;
                                }
                        else
                                {
index ebb42781e6ef9f657ea55fd3dca63ad63108b468..6b2daa1f10ed75cc86874f477e82726d13286ed8 100644 (file)
@@ -321,6 +321,15 @@ DECLARE_STACK_OF(BIO)
 
 typedef struct bio_f_buffer_ctx_struct
        {
+       /* Buffers are setup like this:
+        *
+        * <---------------------- size ----------------------->
+        * +---------------------------------------------------+
+        * | consumed | remaining          | free space        |
+        * +---------------------------------------------------+
+        * <-- off --><------- len ------->
+        */
+
        /* BIO *bio; */ /* this is now in the BIO struct */
        int ibuf_size;  /* how big is the input buffer */
        int obuf_size;  /* how big is the output buffer */