LCOV - code coverage report
Current view: top level - openssh-6.6p1 - buffer.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 77 97 79.4 %
Date: 2014-08-01 Functions: 14 16 87.5 %
Branches: 25 44 56.8 %

           Branch data     Line data    Source code
       1                 :            : /* $OpenBSD: buffer.c,v 1.35 2014/02/02 03:44:31 djm Exp $ */
       2                 :            : /*
       3                 :            :  * Author: Tatu Ylonen <ylo@cs.hut.fi>
       4                 :            :  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
       5                 :            :  *                    All rights reserved
       6                 :            :  * Functions for manipulating fifo buffers (that can grow if needed).
       7                 :            :  *
       8                 :            :  * As far as I am concerned, the code I have written for this software
       9                 :            :  * can be used freely for any purpose.  Any derived versions of this
      10                 :            :  * software must be clearly marked as such, and if the derived work is
      11                 :            :  * incompatible with the protocol description in the RFC file, it must be
      12                 :            :  * called by a name other than "ssh" or "Secure Shell".
      13                 :            :  */
      14                 :            : 
      15                 :            : #include "includes.h"
      16                 :            : 
      17                 :            : #include <sys/param.h>
      18                 :            : 
      19                 :            : #include <stdio.h>
      20                 :            : #include <string.h>
      21                 :            : #include <stdarg.h>
      22                 :            : #include <stdlib.h>
      23                 :            : 
      24                 :            : #include "xmalloc.h"
      25                 :            : #include "buffer.h"
      26                 :            : #include "log.h"
      27                 :            : 
      28                 :            : #define BUFFER_MAX_CHUNK        0x100000
      29                 :            : #define BUFFER_MAX_LEN          0xa00000
      30                 :            : #define BUFFER_ALLOCSZ          0x008000
      31                 :            : 
      32                 :            : /* Initializes the buffer structure. */
      33                 :            : 
      34                 :            : void
      35                 :     967566 : buffer_init(Buffer *buffer)
      36                 :            : {
      37                 :     967566 :         const u_int len = 4096;
      38                 :            : 
      39                 :     967566 :         buffer->alloc = 0;
      40                 :     967566 :         buffer->buf = xmalloc(len);
      41                 :     967566 :         buffer->alloc = len;
      42                 :     967566 :         buffer->offset = 0;
      43                 :     967566 :         buffer->end = 0;
      44                 :     967566 : }
      45                 :            : 
      46                 :            : /* Frees any memory used for the buffer. */
      47                 :            : 
      48                 :            : void
      49                 :     951082 : buffer_free(Buffer *buffer)
      50                 :            : {
      51         [ +  - ]:     951082 :         if (buffer->alloc > 0) {
      52                 :     951082 :                 explicit_bzero(buffer->buf, buffer->alloc);
      53                 :     951082 :                 buffer->alloc = 0;
      54                 :     951082 :                 free(buffer->buf);
      55                 :            :         }
      56                 :     951082 : }
      57                 :            : 
      58                 :            : /*
      59                 :            :  * Clears any data from the buffer, making it empty.  This does not actually
      60                 :            :  * zero the memory.
      61                 :            :  */
      62                 :            : 
      63                 :            : void
      64                 :    4431787 : buffer_clear(Buffer *buffer)
      65                 :            : {
      66                 :    4431787 :         buffer->offset = 0;
      67                 :    4431787 :         buffer->end = 0;
      68                 :    4431787 : }
      69                 :            : 
      70                 :            : /* Appends data to the buffer, expanding it if necessary. */
      71                 :            : 
      72                 :            : void
      73                 :   10058106 : buffer_append(Buffer *buffer, const void *data, u_int len)
      74                 :            : {
      75                 :            :         void *p;
      76                 :   10058106 :         p = buffer_append_space(buffer, len);
      77                 :   10058106 :         memcpy(p, data, len);
      78                 :   10058106 : }
      79                 :            : 
      80                 :            : static int
      81                 :      55336 : buffer_compact(Buffer *buffer)
      82                 :            : {
      83                 :            :         /*
      84                 :            :          * If the buffer is quite empty, but all data is at the end, move the
      85                 :            :          * data to the beginning.
      86                 :            :          */
      87         [ +  + ]:      55336 :         if (buffer->offset > MIN(buffer->alloc, BUFFER_MAX_CHUNK)) {
      88                 :          2 :                 memmove(buffer->buf, buffer->buf + buffer->offset,
      89                 :          2 :                         buffer->end - buffer->offset);
      90                 :          2 :                 buffer->end -= buffer->offset;
      91                 :          2 :                 buffer->offset = 0;
      92                 :          2 :                 return (1);
      93                 :            :         }
      94                 :            :         return (0);
      95                 :            : }
      96                 :            : 
      97                 :            : /*
      98                 :            :  * Appends space to the buffer, expanding the buffer if necessary. This does
      99                 :            :  * not actually copy the data into the buffer, but instead returns a pointer
     100                 :            :  * to the allocated region.
     101                 :            :  */
     102                 :            : 
     103                 :            : void *
     104                 :   13113746 : buffer_append_space(Buffer *buffer, u_int len)
     105                 :            : {
     106                 :            :         u_int newlen;
     107                 :            :         void *p;
     108                 :            : 
     109         [ -  + ]:   13113746 :         if (len > BUFFER_MAX_CHUNK)
     110                 :          0 :                 fatal("buffer_append_space: len %u not supported", len);
     111                 :            : 
     112                 :            :         /* If the buffer is empty, start using it from the beginning. */
     113         [ +  + ]:   13113746 :         if (buffer->offset == buffer->end) {
     114                 :    4661623 :                 buffer->offset = 0;
     115                 :   13119739 :                 buffer->end = 0;
     116                 :            :         }
     117                 :            : restart:
     118                 :            :         /* If there is enough space to store all data, store it now. */
     119         [ +  + ]:   13119741 :         if (buffer->end + len < buffer->alloc) {
     120                 :   13113746 :                 p = buffer->buf + buffer->end;
     121                 :   13113746 :                 buffer->end += len;
     122                 :   13113746 :                 return p;
     123                 :            :         }
     124                 :            : 
     125                 :            :         /* Compact data back to the start of the buffer if necessary */
     126         [ +  + ]:       5995 :         if (buffer_compact(buffer))
     127                 :            :                 goto restart;
     128                 :            : 
     129                 :            :         /* Increase the size of the buffer and retry. */
     130                 :       5993 :         newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
     131         [ -  + ]:       5993 :         if (newlen > BUFFER_MAX_LEN)
     132                 :          0 :                 fatal("buffer_append_space: alloc %u not supported",
     133                 :            :                     newlen);
     134                 :       5993 :         buffer->buf = xrealloc(buffer->buf, 1, newlen);
     135                 :       5993 :         buffer->alloc = newlen;
     136                 :       5993 :         goto restart;
     137                 :            :         /* NOTREACHED */
     138                 :            : }
     139                 :            : 
     140                 :            : /*
     141                 :            :  * Check whether an allocation of 'len' will fit in the buffer
     142                 :            :  * This must follow the same math as buffer_append_space
     143                 :            :  */
     144                 :            : int
     145                 :      67204 : buffer_check_alloc(Buffer *buffer, u_int len)
     146                 :            : {
     147         [ +  + ]:      67204 :         if (buffer->offset == buffer->end) {
     148                 :      61566 :                 buffer->offset = 0;
     149                 :      67204 :                 buffer->end = 0;
     150                 :            :         }
     151                 :            :  restart:
     152         [ +  + ]:      67204 :         if (buffer->end + len < buffer->alloc)
     153                 :            :                 return (1);
     154         [ -  + ]:      49341 :         if (buffer_compact(buffer))
     155                 :            :                 goto restart;
     156         [ -  + ]:      49341 :         if (roundup(buffer->alloc + len, BUFFER_ALLOCSZ) <= BUFFER_MAX_LEN)
     157                 :            :                 return (1);
     158                 :          0 :         return (0);
     159                 :            : }
     160                 :            : 
     161                 :            : /* Returns the number of bytes of data in the buffer. */
     162                 :            : 
     163                 :            : u_int
     164                 :    6995388 : buffer_len(const Buffer *buffer)
     165                 :            : {
     166                 :    6995388 :         return buffer->end - buffer->offset;
     167                 :            : }
     168                 :            : 
     169                 :            : /* Gets data from the beginning of the buffer. */
     170                 :            : 
     171                 :            : int
     172                 :    7324712 : buffer_get_ret(Buffer *buffer, void *buf, u_int len)
     173                 :            : {
     174         [ +  + ]:    7324712 :         if (len > buffer->end - buffer->offset) {
     175                 :          2 :                 error("buffer_get_ret: trying to get more bytes %d than in buffer %d",
     176                 :            :                     len, buffer->end - buffer->offset);
     177                 :          2 :                 return (-1);
     178                 :            :         }
     179                 :    7324710 :         memcpy(buf, buffer->buf + buffer->offset, len);
     180                 :    7324710 :         buffer->offset += len;
     181                 :    7324710 :         return (0);
     182                 :            : }
     183                 :            : 
     184                 :            : void
     185                 :      41724 : buffer_get(Buffer *buffer, void *buf, u_int len)
     186                 :            : {
     187         [ -  + ]:      41724 :         if (buffer_get_ret(buffer, buf, len) == -1)
     188                 :          0 :                 fatal("buffer_get: buffer error");
     189                 :      41724 : }
     190                 :            : 
     191                 :            : /* Consumes the given number of bytes from the beginning of the buffer. */
     192                 :            : 
     193                 :            : int
     194                 :      18583 : buffer_consume_ret(Buffer *buffer, u_int bytes)
     195                 :            : {
     196 [ -  + ][ -  + ]:     166110 :         if (bytes > buffer->end - buffer->offset) {
     197                 :          0 :                 error("buffer_consume_ret: trying to get more bytes than in buffer");
     198                 :          0 :                 return (-1);
     199                 :            :         }
     200                 :     147527 :         buffer->offset += bytes;
     201                 :      18583 :         return (0);
     202                 :            : }
     203                 :            : 
     204                 :            : void
     205                 :     147527 : buffer_consume(Buffer *buffer, u_int bytes)
     206                 :            : {
     207         [ -  + ]:     147527 :         if (buffer_consume_ret(buffer, bytes) == -1)
     208                 :          0 :                 fatal("buffer_consume: buffer error");
     209                 :     147527 : }
     210                 :            : 
     211                 :            : /* Consumes the given number of bytes from the end of the buffer. */
     212                 :            : 
     213                 :            : int
     214                 :          0 : buffer_consume_end_ret(Buffer *buffer, u_int bytes)
     215                 :            : {
     216 [ +  - ][ #  # ]:      24797 :         if (bytes > buffer->end - buffer->offset)
     217                 :            :                 return (-1);
     218                 :      24797 :         buffer->end -= bytes;
     219                 :          0 :         return (0);
     220                 :            : }
     221                 :            : 
     222                 :            : void
     223                 :      24797 : buffer_consume_end(Buffer *buffer, u_int bytes)
     224                 :            : {
     225         [ -  + ]:      24797 :         if (buffer_consume_end_ret(buffer, bytes) == -1)
     226                 :          0 :                 fatal("buffer_consume_end: trying to get more bytes than in buffer");
     227                 :      24797 : }
     228                 :            : 
     229                 :            : /* Returns a pointer to the first used byte in the buffer. */
     230                 :            : 
     231                 :            : void *
     232                 :    4964213 : buffer_ptr(const Buffer *buffer)
     233                 :            : {
     234                 :    4964213 :         return buffer->buf + buffer->offset;
     235                 :            : }
     236                 :            : 
     237                 :            : /* Dumps the contents of the buffer to stderr. */
     238                 :            : 
     239                 :            : void
     240                 :          0 : buffer_dump(const Buffer *buffer)
     241                 :            : {
     242                 :            :         u_int i;
     243                 :          0 :         u_char *ucp = buffer->buf;
     244                 :            : 
     245         [ #  # ]:          0 :         for (i = buffer->offset; i < buffer->end; i++) {
     246                 :          0 :                 fprintf(stderr, "%02x", ucp[i]);
     247         [ #  # ]:          0 :                 if ((i-buffer->offset)%16==15)
     248                 :          0 :                         fprintf(stderr, "\r\n");
     249         [ #  # ]:          0 :                 else if ((i-buffer->offset)%2==1)
     250                 :          0 :                         fprintf(stderr, " ");
     251                 :            :         }
     252                 :          0 :         fprintf(stderr, "\r\n");
     253                 :          0 : }

Generated by: LCOV version 1.9