LCOV - differential code coverage report
Current view: top level - src/common - fe_memutils.c (source / functions) Coverage Total Hit UBC GBC GNC CBC DCB
Current: c38de3ae6098ccf1904109f2e550eb4777f66024 vs e352ac8c5c90ed6ce792f044c22145578542a330 Lines: 62.2 % 111 69 42 3 4 62 4
Current Date: 2026-11-05 14:14:01 +0100 Functions: 80.8 % 26 21 5 1 1 19
Baseline: lcov-20261105-baseline Branches: 45.7 % 92 42 50 3 39
Baseline Date: 2026-11-05 14:14:01 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 100.0 % 4 4 4
(30,360] days: 45.7 % 46 21 25 3 18
(360..) days: 72.1 % 61 44 17 44
Function coverage date bins:
(30,360] days: 58.3 % 12 7 5 1 6
(360..) days: 100.0 % 14 14 1 13
Branch coverage date bins:
(30,360] days: 35.0 % 60 21 39 3 18
(360..) days: 65.6 % 32 21 11 21

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * fe_memutils.c
                                  4                 :                :  *    memory management support for frontend code
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
                                  7                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :                :  *
                                  9                 :                :  *
                                 10                 :                :  * IDENTIFICATION
                                 11                 :                :  *    src/common/fe_memutils.c
                                 12                 :                :  *
                                 13                 :                :  *-------------------------------------------------------------------------
                                 14                 :                :  */
                                 15                 :                : 
                                 16                 :                : #ifndef FRONTEND
                                 17                 :                : #error "This file is not expected to be compiled for backend code"
                                 18                 :                : #endif
                                 19                 :                : 
                                 20                 :                : #include "postgres_fe.h"
                                 21                 :                : 
                                 22                 :                : #include "common/int.h"
                                 23                 :                : 
                                 24                 :                : pg_noreturn static pg_noinline void add_size_error(Size s1, Size s2);
                                 25                 :                : pg_noreturn static pg_noinline void mul_size_error(Size s1, Size s2);
                                 26                 :                : 
                                 27                 :                : 
                                 28                 :                : static inline void *
 4234 fujii@postgresql.org       29                 :CBC     4632922 : pg_malloc_internal(size_t size, int flags)
                                 30                 :                : {
                                 31                 :                :     void       *tmp;
                                 32                 :                : 
                                 33                 :                :     /* Avoid unportable behavior of malloc(0) */
 5014 alvherre@alvh.no-ip.       34         [ +  + ]:        4632922 :     if (size == 0)
                                 35                 :           3437 :         size = 1;
                                 36                 :        4632922 :     tmp = malloc(size);
 4234 fujii@postgresql.org       37         [ -  + ]:        4632922 :     if (tmp == NULL)
                                 38                 :                :     {
 4234 fujii@postgresql.org       39         [ #  # ]:UBC           0 :         if ((flags & MCXT_ALLOC_NO_OOM) == 0)
                                 40                 :                :         {
                                 41                 :              0 :             fprintf(stderr, _("out of memory\n"));
                                 42                 :              0 :             exit(EXIT_FAILURE);
                                 43                 :                :         }
                                 44                 :              0 :         return NULL;
                                 45                 :                :     }
                                 46                 :                : 
 4234 fujii@postgresql.org       47         [ +  + ]:CBC     4632922 :     if ((flags & MCXT_ALLOC_ZERO) != 0)
                                 48   [ +  -  +  +  :        6528972 :         MemSet(tmp, 0, size);
                                     +  -  +  +  +  
                                                 + ]
 5014 alvherre@alvh.no-ip.       49                 :        4632922 :     return tmp;
                                 50                 :                : }
                                 51                 :                : 
                                 52                 :                : void *
 4234 fujii@postgresql.org       53                 :        2177051 : pg_malloc(size_t size)
                                 54                 :                : {
                                 55                 :        2177051 :     return pg_malloc_internal(size, 0);
                                 56                 :                : }
                                 57                 :                : 
                                 58                 :                : void *
 5014 alvherre@alvh.no-ip.       59                 :        1708629 : pg_malloc0(size_t size)
                                 60                 :                : {
 4234 fujii@postgresql.org       61                 :        1708629 :     return pg_malloc_internal(size, MCXT_ALLOC_ZERO);
                                 62                 :                : }
                                 63                 :                : 
                                 64                 :                : void *
                                 65                 :          78005 : pg_malloc_extended(size_t size, int flags)
                                 66                 :                : {
                                 67                 :          78005 :     return pg_malloc_internal(size, flags);
                                 68                 :                : }
                                 69                 :                : 
                                 70                 :                : void *
 5014 alvherre@alvh.no-ip.       71                 :          94176 : pg_realloc(void *ptr, size_t size)
                                 72                 :                : {
                                 73                 :                :     void       *tmp;
                                 74                 :                : 
                                 75                 :                :     /* Avoid unportable behavior of realloc(NULL, 0) */
 4908 bruce@momjian.us           76   [ +  +  -  + ]:          94176 :     if (ptr == NULL && size == 0)
 4908 bruce@momjian.us           77                 :UBC           0 :         size = 1;
 4908 bruce@momjian.us           78                 :CBC       94176 :     tmp = realloc(ptr, size);
                                 79         [ -  + ]:          94176 :     if (!tmp)
                                 80                 :                :     {
 5014 alvherre@alvh.no-ip.       81                 :UBC           0 :         fprintf(stderr, _("out of memory\n"));
                                 82                 :              0 :         exit(EXIT_FAILURE);
                                 83                 :                :     }
 4908 bruce@momjian.us           84                 :CBC       94176 :     return tmp;
                                 85                 :                : }
                                 86                 :                : 
                                 87                 :                : /*
                                 88                 :                :  * "Safe" wrapper around strdup().
                                 89                 :                :  */
                                 90                 :                : char *
 5014 alvherre@alvh.no-ip.       91                 :        8149027 : pg_strdup(const char *in)
                                 92                 :                : {
                                 93                 :                :     char       *tmp;
                                 94                 :                : 
                                 95         [ -  + ]:        8149027 :     if (!in)
                                 96                 :                :     {
 5014 alvherre@alvh.no-ip.       97                 :UBC           0 :         fprintf(stderr,
                                 98                 :              0 :                 _("cannot duplicate null pointer (internal error)\n"));
                                 99                 :              0 :         exit(EXIT_FAILURE);
                                100                 :                :     }
 5014 alvherre@alvh.no-ip.      101                 :CBC     8149027 :     tmp = strdup(in);
                                102         [ -  + ]:        8149027 :     if (!tmp)
                                103                 :                :     {
 5014 alvherre@alvh.no-ip.      104                 :UBC           0 :         fprintf(stderr, _("out of memory\n"));
                                105                 :              0 :         exit(EXIT_FAILURE);
                                106                 :                :     }
 5014 alvherre@alvh.no-ip.      107                 :CBC     8149027 :     return tmp;
                                108                 :                : }
                                109                 :                : 
                                110                 :                : void
                                111                 :        7735062 : pg_free(void *ptr)
                                112                 :                : {
 1603 peter@eisentraut.org      113                 :        7735062 :     free(ptr);
 5014 alvherre@alvh.no-ip.      114                 :        7735062 : }
                                115                 :                : 
                                116                 :                : /*
                                117                 :                :  * Frontend emulation of backend memory management functions.  Useful for
                                118                 :                :  * programs that compile backend files.
                                119                 :                :  */
                                120                 :                : void *
                                121                 :         665514 : palloc(Size size)
                                122                 :                : {
 4234 fujii@postgresql.org      123                 :         665514 :     return pg_malloc_internal(size, 0);
                                124                 :                : }
                                125                 :                : 
                                126                 :                : void *
 5014 alvherre@alvh.no-ip.      127                 :           3204 : palloc0(Size size)
                                128                 :                : {
 4234 fujii@postgresql.org      129                 :           3204 :     return pg_malloc_internal(size, MCXT_ALLOC_ZERO);
                                130                 :                : }
                                131                 :                : 
                                132                 :                : void *
                                133                 :            519 : palloc_extended(Size size, int flags)
                                134                 :                : {
                                135                 :            519 :     return pg_malloc_internal(size, flags);
                                136                 :                : }
                                137                 :                : 
                                138                 :                : void
 5014 alvherre@alvh.no-ip.      139                 :        2221227 : pfree(void *pointer)
                                140                 :                : {
                                141                 :        2221227 :     pg_free(pointer);
                                142                 :        2221227 : }
                                143                 :                : 
                                144                 :                : char *
                                145                 :        1281353 : pstrdup(const char *in)
                                146                 :                : {
                                147                 :        1281353 :     return pg_strdup(in);
                                148                 :                : }
                                149                 :                : 
                                150                 :                : char *
 2528                           151                 :            311 : pnstrdup(const char *in, Size size)
                                152                 :                : {
                                153                 :                :     char       *tmp;
                                154                 :                : 
                                155         [ -  + ]:            311 :     if (!in)
                                156                 :                :     {
 2528 alvherre@alvh.no-ip.      157                 :UBC           0 :         fprintf(stderr,
                                158                 :              0 :                 _("cannot duplicate null pointer (internal error)\n"));
                                159                 :              0 :         exit(EXIT_FAILURE);
                                160                 :                :     }
                                161                 :                : 
   15 drowley@postgresql.o      162                 :GNC         311 :     size = strnlen(in, size);
                                163                 :            311 :     tmp = malloc(size + 1);
 2528 alvherre@alvh.no-ip.      164         [ -  + ]:CBC         311 :     if (tmp == NULL)
                                165                 :                :     {
 2528 alvherre@alvh.no-ip.      166                 :UBC           0 :         fprintf(stderr, _("out of memory\n"));
                                167                 :              0 :         exit(EXIT_FAILURE);
                                168                 :                :     }
                                169                 :                : 
   15 drowley@postgresql.o      170                 :GNC         311 :     memcpy(tmp, in, size);
                                171                 :            311 :     tmp[size] = '\0';
                                172                 :                : 
 2528 alvherre@alvh.no-ip.      173                 :CBC         311 :     return tmp;
                                174                 :                : }
                                175                 :                : 
                                176                 :                : void *
 5014                           177                 :          59000 : repalloc(void *pointer, Size size)
                                178                 :                : {
                                179                 :          59000 :     return pg_realloc(pointer, size);
                                180                 :                : }
                                181                 :                : 
                                182                 :                : /*
                                183                 :                :  * Support for safe calculation of memory request sizes
                                184                 :                :  *
                                185                 :                :  * These functions perform the requested calculation, but throw error if the
                                186                 :                :  * result overflows.
                                187                 :                :  *
                                188                 :                :  * An important property of these functions is that if an argument was a
                                189                 :                :  * negative signed int before promotion (implying overflow in calculating it)
                                190                 :                :  * we will detect that as an error.  That happens because we reject results
                                191                 :                :  * larger than SIZE_MAX / 2.  In the backend we rely on later checks to do
                                192                 :                :  * that, but in frontend we must do it here.
                                193                 :                :  */
                                194                 :                : Size
  178 tgl@sss.pgh.pa.us         195                 :            110 : add_size(Size s1, Size s2)
                                196                 :                : {
                                197                 :                :     Size        result;
                                198                 :                : 
                                199   [ +  -  -  +  :            110 :     if (unlikely(pg_add_size_overflow(s1, s2, &result) ||
                                              -  + ]
                                200                 :                :                  result > (SIZE_MAX / 2)))
  178 tgl@sss.pgh.pa.us         201                 :UBC           0 :         add_size_error(s1, s2);
  178 tgl@sss.pgh.pa.us         202                 :CBC         110 :     return result;
                                203                 :                : }
                                204                 :                : 
                                205                 :                : pg_noreturn static pg_noinline void
  178 tgl@sss.pgh.pa.us         206                 :UBC           0 : add_size_error(Size s1, Size s2)
                                207                 :                : {
                                208                 :              0 :     fprintf(stderr, _("invalid memory allocation request size %zu + %zu\n"),
                                209                 :                :             s1, s2);
                                210                 :              0 :     exit(EXIT_FAILURE);
                                211                 :                : }
                                212                 :                : 
                                213                 :                : Size
  178 tgl@sss.pgh.pa.us         214                 :CBC         110 : mul_size(Size s1, Size s2)
                                215                 :                : {
                                216                 :                :     Size        result;
                                217                 :                : 
                                218   [ +  -  -  +  :            110 :     if (unlikely(pg_mul_size_overflow(s1, s2, &result) ||
                                              -  + ]
                                219                 :                :                  result > (SIZE_MAX / 2)))
  178 tgl@sss.pgh.pa.us         220                 :UBC           0 :         mul_size_error(s1, s2);
  178 tgl@sss.pgh.pa.us         221                 :CBC         110 :     return result;
                                222                 :                : }
                                223                 :                : 
                                224                 :                : pg_noreturn static pg_noinline void
  178 tgl@sss.pgh.pa.us         225                 :UBC           0 : mul_size_error(Size s1, Size s2)
                                226                 :                : {
                                227                 :              0 :     fprintf(stderr, _("invalid memory allocation request size %zu * %zu\n"),
                                228                 :                :             s1, s2);
                                229                 :              0 :     exit(EXIT_FAILURE);
                                230                 :                : }
                                231                 :                : 
                                232                 :                : /*
                                233                 :                :  * pg_malloc_mul
                                234                 :                :  *      Equivalent to pg_malloc(mul_size(s1, s2)).
                                235                 :                :  */
                                236                 :                : void *
  178 tgl@sss.pgh.pa.us         237                 :CBC     1187481 : pg_malloc_mul(Size s1, Size s2)
                                238                 :                : {
                                239                 :                :     /* inline mul_size() for efficiency */
                                240                 :                :     Size        req;
                                241                 :                : 
                                242   [ +  -  -  +  :        1187481 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              -  + ]
                                243                 :                :                  req > (SIZE_MAX / 2)))
  178 tgl@sss.pgh.pa.us         244                 :UBC           0 :         mul_size_error(s1, s2);
  178 tgl@sss.pgh.pa.us         245                 :CBC     1187481 :     return pg_malloc(req);
                                246                 :                : }
                                247                 :                : 
                                248                 :                : /*
                                249                 :                :  * pg_malloc0_mul
                                250                 :                :  *      Equivalent to pg_malloc0(mul_size(s1, s2)).
                                251                 :                :  *
                                252                 :                :  * This is comparable to standard calloc's behavior.
                                253                 :                :  */
                                254                 :                : void *
                                255                 :        1578534 : pg_malloc0_mul(Size s1, Size s2)
                                256                 :                : {
                                257                 :                :     /* inline mul_size() for efficiency */
                                258                 :                :     Size        req;
                                259                 :                : 
                                260   [ +  -  -  +  :        1578534 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              -  + ]
                                261                 :                :                  req > (SIZE_MAX / 2)))
  178 tgl@sss.pgh.pa.us         262                 :UBC           0 :         mul_size_error(s1, s2);
  178 tgl@sss.pgh.pa.us         263                 :CBC     1578534 :     return pg_malloc0(req);
                                264                 :                : }
                                265                 :                : 
                                266                 :                : /*
                                267                 :                :  * pg_malloc_mul_extended
                                268                 :                :  *      Equivalent to pg_malloc_extended(mul_size(s1, s2), flags).
                                269                 :                :  */
                                270                 :                : void *
  178 tgl@sss.pgh.pa.us         271                 :UBC           0 : pg_malloc_mul_extended(Size s1, Size s2, int flags)
                                272                 :                : {
                                273                 :                :     /* inline mul_size() for efficiency */
                                274                 :                :     Size        req;
                                275                 :                : 
                                276   [ #  #  #  #  :              0 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              #  # ]
                                277                 :                :                  req > (SIZE_MAX / 2)))
                                278                 :              0 :         mul_size_error(s1, s2);
                                279                 :              0 :     return pg_malloc_extended(req, flags);
                                280                 :                : }
                                281                 :                : 
                                282                 :                : /*
                                283                 :                :  * pg_realloc_mul
                                284                 :                :  *      Equivalent to pg_realloc(p, mul_size(s1, s2)).
                                285                 :                :  */
                                286                 :                : void *
  178 tgl@sss.pgh.pa.us         287                 :CBC       33806 : pg_realloc_mul(void *p, Size s1, Size s2)
                                288                 :                : {
                                289                 :                :     /* inline mul_size() for efficiency */
                                290                 :                :     Size        req;
                                291                 :                : 
                                292   [ +  -  -  +  :          33806 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              -  + ]
                                293                 :                :                  req > (SIZE_MAX / 2)))
  178 tgl@sss.pgh.pa.us         294                 :UBC           0 :         mul_size_error(s1, s2);
  178 tgl@sss.pgh.pa.us         295                 :CBC       33806 :     return pg_realloc(p, req);
                                296                 :                : }
                                297                 :                : 
                                298                 :                : /*
                                299                 :                :  * palloc_mul
                                300                 :                :  *      Equivalent to palloc(mul_size(s1, s2)).
                                301                 :                :  */
                                302                 :                : void *
                                303                 :           4576 : palloc_mul(Size s1, Size s2)
                                304                 :                : {
                                305                 :                :     /* inline mul_size() for efficiency */
                                306                 :                :     Size        req;
                                307                 :                : 
                                308   [ +  -  -  +  :           4576 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              -  + ]
                                309                 :                :                  req > (SIZE_MAX / 2)))
  178 tgl@sss.pgh.pa.us         310                 :UBC           0 :         mul_size_error(s1, s2);
  178 tgl@sss.pgh.pa.us         311                 :CBC        4576 :     return palloc(req);
                                312                 :                : }
                                313                 :                : 
                                314                 :                : /*
                                315                 :                :  * palloc0_mul
                                316                 :                :  *      Equivalent to palloc0(mul_size(s1, s2)).
                                317                 :                :  *
                                318                 :                :  * This is comparable to standard calloc's behavior.
                                319                 :                :  */
                                320                 :                : void *
  178 tgl@sss.pgh.pa.us         321                 :UBC           0 : palloc0_mul(Size s1, Size s2)
                                322                 :                : {
                                323                 :                :     /* inline mul_size() for efficiency */
                                324                 :                :     Size        req;
                                325                 :                : 
                                326   [ #  #  #  #  :              0 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              #  # ]
                                327                 :                :                  req > (SIZE_MAX / 2)))
                                328                 :              0 :         mul_size_error(s1, s2);
                                329                 :              0 :     return palloc0(req);
                                330                 :                : }
                                331                 :                : 
                                332                 :                : /*
                                333                 :                :  * palloc_mul_extended
                                334                 :                :  *      Equivalent to palloc_extended(mul_size(s1, s2), flags).
                                335                 :                :  */
                                336                 :                : void *
                                337                 :              0 : palloc_mul_extended(Size s1, Size s2, int flags)
                                338                 :                : {
                                339                 :                :     /* inline mul_size() for efficiency */
                                340                 :                :     Size        req;
                                341                 :                : 
                                342   [ #  #  #  #  :              0 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              #  # ]
                                343                 :                :                  req > (SIZE_MAX / 2)))
                                344                 :              0 :         mul_size_error(s1, s2);
                                345                 :              0 :     return palloc_extended(req, flags);
                                346                 :                : }
                                347                 :                : 
                                348                 :                : /*
                                349                 :                :  * repalloc_mul
                                350                 :                :  *      Equivalent to repalloc(p, mul_size(s1, s2)).
                                351                 :                :  */
                                352                 :                : void *
  178 tgl@sss.pgh.pa.us         353                 :GBC         220 : repalloc_mul(void *p, Size s1, Size s2)
                                354                 :                : {
                                355                 :                :     /* inline mul_size() for efficiency */
                                356                 :                :     Size        req;
                                357                 :                : 
                                358   [ +  -  -  +  :            220 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              -  + ]
                                359                 :                :                  req > (SIZE_MAX / 2)))
  178 tgl@sss.pgh.pa.us         360                 :UBC           0 :         mul_size_error(s1, s2);
  178 tgl@sss.pgh.pa.us         361                 :GBC         220 :     return repalloc(p, req);
                                362                 :                : }
        

Generated by: LCOV version 2.0-1