LCOV - code coverage report
Current view: top level - lib/dpkg - varbuf.c (source / functions) Hit Total Coverage
Test: dpkg 1.21.11 C code coverage Lines: 102 109 93.6 %
Date: 2022-12-03 00:40:01 Functions: 21 21 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 25 32 78.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * libdpkg - Debian packaging suite library routines
       3                 :            :  * varbuf.c - variable length expandable buffer handling
       4                 :            :  *
       5                 :            :  * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
       6                 :            :  * Copyright © 2008-2015 Guillem Jover <guillem@debian.org>
       7                 :            :  *
       8                 :            :  * This is free software; you can redistribute it and/or modify
       9                 :            :  * it under the terms of the GNU General Public License as published by
      10                 :            :  * the Free Software Foundation; either version 2 of the License, or
      11                 :            :  * (at your option) any later version.
      12                 :            :  *
      13                 :            :  * This is distributed in the hope that it will be useful,
      14                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16                 :            :  * GNU General Public License for more details.
      17                 :            :  *
      18                 :            :  * You should have received a copy of the GNU General Public License
      19                 :            :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      20                 :            :  */
      21                 :            : 
      22                 :            : #include <config.h>
      23                 :            : #include <compat.h>
      24                 :            : 
      25                 :            : #include <string.h>
      26                 :            : #include <stdlib.h>
      27                 :            : #include <stdio.h>
      28                 :            : 
      29                 :            : #include <dpkg/i18n.h>
      30                 :            : #include <dpkg/dpkg.h>
      31                 :            : #include <dpkg/dpkg-db.h>
      32                 :            : 
      33                 :            : void
      34                 :        240 : varbuf_add_char(struct varbuf *v, int c)
      35                 :            : {
      36                 :        240 :   varbuf_grow(v, 1);
      37                 :        240 :   v->buf[v->used++]= c;
      38                 :        240 : }
      39                 :            : 
      40                 :            : void
      41                 :          2 : varbuf_dup_char(struct varbuf *v, int c, size_t n)
      42                 :            : {
      43         [ -  + ]:          2 :   if (n == 0)
      44                 :          0 :     return;
      45                 :          2 :   varbuf_grow(v, n);
      46                 :          2 :   memset(v->buf + v->used, c, n);
      47                 :          2 :   v->used += n;
      48                 :            : }
      49                 :            : 
      50                 :            : void
      51                 :          1 : varbuf_map_char(struct varbuf *v, int c_src, int c_dst)
      52                 :            : {
      53                 :            :   size_t i;
      54                 :            : 
      55         [ +  + ]:         16 :   for (i = 0; i < v->used; i++)
      56         [ +  + ]:         15 :     if (v->buf[i] == c_src)
      57                 :          3 :       v->buf[i] = c_dst;
      58                 :          1 : }
      59                 :            : 
      60                 :            : int
      61                 :        255 : varbuf_printf(struct varbuf *v, const char *fmt, ...)
      62                 :            : {
      63                 :            :   int r;
      64                 :            :   va_list args;
      65                 :            : 
      66                 :        255 :   va_start(args, fmt);
      67                 :        255 :   r = varbuf_vprintf(v, fmt, args);
      68                 :        255 :   va_end(args);
      69                 :            : 
      70                 :        255 :   return r;
      71                 :            : }
      72                 :            : 
      73                 :            : int
      74                 :        382 : varbuf_vprintf(struct varbuf *v, const char *fmt, va_list args)
      75                 :            : {
      76                 :            :   va_list args_copy;
      77                 :            :   int needed, r;
      78                 :            : 
      79                 :        382 :   va_copy(args_copy, args);
      80                 :        382 :   needed = vsnprintf(NULL, 0, fmt, args_copy);
      81                 :        382 :   va_end(args_copy);
      82                 :            : 
      83         [ -  + ]:        382 :   if (needed < 0)
      84                 :          0 :     ohshite(_("error formatting string into varbuf variable"));
      85                 :            : 
      86                 :        382 :   varbuf_grow(v, needed + 1);
      87                 :            : 
      88                 :        382 :   r = vsnprintf(v->buf + v->used, needed + 1, fmt, args);
      89         [ -  + ]:        382 :   if (r < 0)
      90                 :          0 :     ohshite(_("error formatting string into varbuf variable"));
      91                 :            : 
      92                 :        382 :   v->used += r;
      93                 :            : 
      94                 :        382 :   return r;
      95                 :            : }
      96                 :            : 
      97                 :            : void
      98                 :        814 : varbuf_add_buf(struct varbuf *v, const void *s, size_t size)
      99                 :            : {
     100         [ +  + ]:        814 :   if (size == 0)
     101                 :          5 :     return;
     102                 :        809 :   varbuf_grow(v, size);
     103                 :        809 :   memcpy(v->buf + v->used, s, size);
     104                 :        809 :   v->used += size;
     105                 :            : }
     106                 :            : 
     107                 :            : void
     108                 :        178 : varbuf_add_dir(struct varbuf *v, const char *dirname)
     109                 :            : {
     110                 :        178 :   varbuf_add_str(v, dirname);
     111   [ +  +  +  + ]:        178 :   if (v->used == 0 || v->buf[v->used - 1] != '/')
     112                 :        175 :     varbuf_add_char(v, '/');
     113                 :        178 : }
     114                 :            : 
     115                 :            : void
     116                 :        551 : varbuf_end_str(struct varbuf *v)
     117                 :            : {
     118                 :        551 :   varbuf_grow(v, 1);
     119                 :        551 :   v->buf[v->used] = '\0';
     120                 :        551 : }
     121                 :            : 
     122                 :            : const char *
     123                 :          2 : varbuf_get_str(struct varbuf *v)
     124                 :            : {
     125                 :          2 :   varbuf_end_str(v);
     126                 :            : 
     127                 :          2 :   return v->buf;
     128                 :            : }
     129                 :            : 
     130                 :            : struct varbuf *
     131                 :          2 : varbuf_new(size_t size)
     132                 :            : {
     133                 :            :   struct varbuf *v;
     134                 :            : 
     135                 :          2 :   v = m_malloc(sizeof(*v));
     136                 :          2 :   varbuf_init(v, size);
     137                 :            : 
     138                 :          2 :   return v;
     139                 :            : }
     140                 :            : 
     141                 :            : void
     142                 :         98 : varbuf_init(struct varbuf *v, size_t size)
     143                 :            : {
     144                 :         98 :   v->used = 0;
     145                 :         98 :   v->size = size;
     146         [ +  + ]:         98 :   if (size)
     147                 :         89 :     v->buf = m_malloc(size);
     148                 :            :   else
     149                 :          9 :     v->buf = NULL;
     150                 :         98 : }
     151                 :            : 
     152                 :            : void
     153                 :        529 : varbuf_reset(struct varbuf *v)
     154                 :            : {
     155                 :        529 :   v->used= 0;
     156                 :        529 : }
     157                 :            : 
     158                 :            : void
     159                 :       1998 : varbuf_grow(struct varbuf *v, size_t need_size)
     160                 :            : {
     161                 :            :   size_t new_size;
     162                 :            : 
     163                 :            :   /* Make sure the varbuf is in a sane state. */
     164         [ -  + ]:       1998 :   if (v->size < v->used)
     165                 :          0 :     internerr("varbuf used(%zu) > size(%zu)", v->used, v->size);
     166                 :            : 
     167                 :            :   /* Check if we already have enough room. */
     168         [ +  + ]:       1998 :   if ((v->size - v->used) >= need_size)
     169                 :       1363 :     return;
     170                 :            : 
     171                 :            :   /* Check if we overflow. */
     172                 :        635 :   new_size = (v->size + need_size) * 2;
     173         [ +  + ]:        635 :   if (new_size < v->size)
     174                 :          2 :     ohshit(_("cannot grow varbuf to size %zu; it would overflow"), need_size);
     175                 :            : 
     176                 :        633 :   v->size = new_size;
     177                 :        633 :   v->buf = m_realloc(v->buf, v->size);
     178                 :            : }
     179                 :            : 
     180                 :            : void
     181                 :          5 : varbuf_trunc(struct varbuf *v, size_t used_size)
     182                 :            : {
     183                 :            :   /* Make sure the caller does not claim more than available. */
     184         [ -  + ]:          5 :   if (v->size < used_size)
     185                 :          0 :     internerr("varbuf new_used(%zu) > size(%zu)", used_size, v->size);
     186                 :            : 
     187                 :          5 :   v->used = used_size;
     188                 :          5 : }
     189                 :            : 
     190                 :            : void
     191                 :         76 : varbuf_snapshot(struct varbuf *v, struct varbuf_state *vs)
     192                 :            : {
     193                 :         76 :   vs->v = v;
     194                 :         76 :   vs->used = v->used;
     195                 :         76 : }
     196                 :            : 
     197                 :            : void
     198                 :          2 : varbuf_rollback(struct varbuf_state *vs)
     199                 :            : {
     200                 :          2 :   varbuf_trunc(vs->v, vs->used);
     201                 :          2 : }
     202                 :            : 
     203                 :            : size_t
     204                 :          7 : varbuf_rollback_len(struct varbuf_state *vs)
     205                 :            : {
     206         [ -  + ]:          7 :   if (vs->used > vs->v->used)
     207                 :          0 :     internerr("varbuf state_used(%zu) > used(%zu)", vs->used, vs->v->used);
     208                 :          7 :   return vs->v->used - vs->used;
     209                 :            : }
     210                 :            : 
     211                 :            : const char *
     212                 :         14 : varbuf_rollback_start(struct varbuf_state *vs)
     213                 :            : {
     214         [ +  + ]:         14 :   if (vs->v->buf == NULL) {
     215         [ -  + ]:          2 :     if (vs->used)
     216                 :          0 :       internerr("varbuf buf(NULL) state_used(%zu) > 0", vs->used);
     217                 :            :     /* XXX: Ideally this would be handled by varbuf always having a valid
     218                 :            :      * buf or switching all users to the getter, but for now this will do. */
     219                 :          2 :     return "";
     220                 :            :   }
     221                 :         12 :   return vs->v->buf + vs->used;
     222                 :            : }
     223                 :            : 
     224                 :            : char *
     225                 :        140 : varbuf_detach(struct varbuf *v)
     226                 :            : {
     227                 :        140 :   char *buf = v->buf;
     228                 :            : 
     229                 :        140 :   v->buf = NULL;
     230                 :        140 :   v->size = 0;
     231                 :        140 :   v->used = 0;
     232                 :            : 
     233                 :        140 :   return buf;
     234                 :            : }
     235                 :            : 
     236                 :            : void
     237                 :        301 : varbuf_destroy(struct varbuf *v)
     238                 :            : {
     239                 :        301 :   free(v->buf); v->buf=NULL; v->size=0; v->used=0;
     240                 :        301 : }
     241                 :            : 
     242                 :            : void
     243                 :          2 : varbuf_free(struct varbuf *v)
     244                 :            : {
     245                 :          2 :   free(v->buf);
     246                 :          2 :   free(v);
     247                 :          2 : }

Generated by: LCOV version 1.16