LCOV - differential code coverage report
Current view: top level - src/common - fe_memutils.c (source / functions) Coverage Total Hit UBC GBC CBC
Current: 380a8b2ea024c33a35e7abc8628e7c4f52f9f9f9 vs db5ed03217b9c238703df8b4b286115d6e940488 Lines: 54.1 % 111 60 51 3 57
Current Date: 2026-05-29 21:51:00 -0400 Functions: 69.2 % 26 18 8 1 17
Baseline: lcov-20260530-034037-baseline Branches: 35.9 % 92 33 59 3 30
Baseline Date: 2026-05-29 14:39:03 -0700 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 26.1 % 46 12 34 3 9
(360..) days: 73.8 % 65 48 17 48
Function coverage date bins:
(7,30] days: 33.3 % 12 4 8 1 3
(360..) days: 100.0 % 14 14 14
Branch coverage date bins:
(7,30] days: 20.0 % 60 12 48 3 9
(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 *
 4075 fujii@postgresql.org       29                 :CBC     5170262 : pg_malloc_internal(size_t size, int flags)
                                 30                 :                : {
                                 31                 :                :     void       *tmp;
                                 32                 :                : 
                                 33                 :                :     /* Avoid unportable behavior of malloc(0) */
 4855 alvherre@alvh.no-ip.       34         [ +  + ]:        5170262 :     if (size == 0)
                                 35                 :           4493 :         size = 1;
                                 36                 :        5170262 :     tmp = malloc(size);
 4075 fujii@postgresql.org       37         [ -  + ]:        5170262 :     if (tmp == NULL)
                                 38                 :                :     {
 4075 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                 :                : 
 4075 fujii@postgresql.org       47         [ +  + ]:CBC     5170262 :     if ((flags & MCXT_ALLOC_ZERO) != 0)
                                 48   [ +  -  +  +  :        6522633 :         MemSet(tmp, 0, size);
                                     +  -  +  +  +  
                                                 + ]
 4855 alvherre@alvh.no-ip.       49                 :        5170262 :     return tmp;
                                 50                 :                : }
                                 51                 :                : 
                                 52                 :                : void *
 4075 fujii@postgresql.org       53                 :        2259532 : pg_malloc(size_t size)
                                 54                 :                : {
                                 55                 :        2259532 :     return pg_malloc_internal(size, 0);
                                 56                 :                : }
                                 57                 :                : 
                                 58                 :                : void *
 4855 alvherre@alvh.no-ip.       59                 :        1679294 : pg_malloc0(size_t size)
                                 60                 :                : {
 4075 fujii@postgresql.org       61                 :        1679294 :     return pg_malloc_internal(size, MCXT_ALLOC_ZERO);
                                 62                 :                : }
                                 63                 :                : 
                                 64                 :                : void *
                                 65                 :          77100 : pg_malloc_extended(size_t size, int flags)
                                 66                 :                : {
                                 67                 :          77100 :     return pg_malloc_internal(size, flags);
                                 68                 :                : }
                                 69                 :                : 
                                 70                 :                : void *
 4855 alvherre@alvh.no-ip.       71                 :          96181 : pg_realloc(void *ptr, size_t size)
                                 72                 :                : {
                                 73                 :                :     void       *tmp;
                                 74                 :                : 
                                 75                 :                :     /* Avoid unportable behavior of realloc(NULL, 0) */
 4749 bruce@momjian.us           76   [ +  +  -  + ]:          96181 :     if (ptr == NULL && size == 0)
 4749 bruce@momjian.us           77                 :UBC           0 :         size = 1;
 4749 bruce@momjian.us           78                 :CBC       96181 :     tmp = realloc(ptr, size);
                                 79         [ -  + ]:          96181 :     if (!tmp)
                                 80                 :                :     {
 4855 alvherre@alvh.no-ip.       81                 :UBC           0 :         fprintf(stderr, _("out of memory\n"));
                                 82                 :              0 :         exit(EXIT_FAILURE);
                                 83                 :                :     }
 4749 bruce@momjian.us           84                 :CBC       96181 :     return tmp;
                                 85                 :                : }
                                 86                 :                : 
                                 87                 :                : /*
                                 88                 :                :  * "Safe" wrapper around strdup().
                                 89                 :                :  */
                                 90                 :                : char *
 4855 alvherre@alvh.no-ip.       91                 :        8897514 : pg_strdup(const char *in)
                                 92                 :                : {
                                 93                 :                :     char       *tmp;
                                 94                 :                : 
                                 95         [ -  + ]:        8897514 :     if (!in)
                                 96                 :                :     {
 4855 alvherre@alvh.no-ip.       97                 :UBC           0 :         fprintf(stderr,
                                 98                 :              0 :                 _("cannot duplicate null pointer (internal error)\n"));
                                 99                 :              0 :         exit(EXIT_FAILURE);
                                100                 :                :     }
 4855 alvherre@alvh.no-ip.      101                 :CBC     8897514 :     tmp = strdup(in);
                                102         [ -  + ]:        8897514 :     if (!tmp)
                                103                 :                :     {
 4855 alvherre@alvh.no-ip.      104                 :UBC           0 :         fprintf(stderr, _("out of memory\n"));
                                105                 :              0 :         exit(EXIT_FAILURE);
                                106                 :                :     }
 4855 alvherre@alvh.no-ip.      107                 :CBC     8897514 :     return tmp;
                                108                 :                : }
                                109                 :                : 
                                110                 :                : void
                                111                 :        5623472 : pg_free(void *ptr)
                                112                 :                : {
 1444 peter@eisentraut.org      113                 :        5623472 :     free(ptr);
 4855 alvherre@alvh.no-ip.      114                 :        5623472 : }
                                115                 :                : 
                                116                 :                : /*
                                117                 :                :  * Frontend emulation of backend memory management functions.  Useful for
                                118                 :                :  * programs that compile backend files.
                                119                 :                :  */
                                120                 :                : void *
                                121                 :        1150659 : palloc(Size size)
                                122                 :                : {
 4075 fujii@postgresql.org      123                 :        1150659 :     return pg_malloc_internal(size, 0);
                                124                 :                : }
                                125                 :                : 
                                126                 :                : void *
 4855 alvherre@alvh.no-ip.      127                 :           3161 : palloc0(Size size)
                                128                 :                : {
 4075 fujii@postgresql.org      129                 :           3161 :     return pg_malloc_internal(size, MCXT_ALLOC_ZERO);
                                130                 :                : }
                                131                 :                : 
                                132                 :                : void *
                                133                 :            516 : palloc_extended(Size size, int flags)
                                134                 :                : {
                                135                 :            516 :     return pg_malloc_internal(size, flags);
                                136                 :                : }
                                137                 :                : 
                                138                 :                : void
 4855 alvherre@alvh.no-ip.      139                 :        2753621 : pfree(void *pointer)
                                140                 :                : {
                                141                 :        2753621 :     pg_free(pointer);
                                142                 :        2753621 : }
                                143                 :                : 
                                144                 :                : char *
                                145                 :        1325639 : pstrdup(const char *in)
                                146                 :                : {
                                147                 :        1325639 :     return pg_strdup(in);
                                148                 :                : }
                                149                 :                : 
                                150                 :                : char *
 2369                           151                 :            331 : pnstrdup(const char *in, Size size)
                                152                 :                : {
                                153                 :                :     char       *tmp;
                                154                 :                :     int         len;
                                155                 :                : 
                                156         [ -  + ]:            331 :     if (!in)
                                157                 :                :     {
 2369 alvherre@alvh.no-ip.      158                 :UBC           0 :         fprintf(stderr,
                                159                 :              0 :                 _("cannot duplicate null pointer (internal error)\n"));
                                160                 :              0 :         exit(EXIT_FAILURE);
                                161                 :                :     }
                                162                 :                : 
 2369 alvherre@alvh.no-ip.      163                 :CBC         331 :     len = strnlen(in, size);
                                164                 :            331 :     tmp = malloc(len + 1);
                                165         [ -  + ]:            331 :     if (tmp == NULL)
                                166                 :                :     {
 2369 alvherre@alvh.no-ip.      167                 :UBC           0 :         fprintf(stderr, _("out of memory\n"));
                                168                 :              0 :         exit(EXIT_FAILURE);
                                169                 :                :     }
                                170                 :                : 
 2369 alvherre@alvh.no-ip.      171                 :CBC         331 :     memcpy(tmp, in, len);
                                172                 :            331 :     tmp[len] = '\0';
                                173                 :                : 
                                174                 :            331 :     return tmp;
                                175                 :                : }
                                176                 :                : 
                                177                 :                : void *
 4855                           178                 :          59037 : repalloc(void *pointer, Size size)
                                179                 :                : {
                                180                 :          59037 :     return pg_realloc(pointer, size);
                                181                 :                : }
                                182                 :                : 
                                183                 :                : /*
                                184                 :                :  * Support for safe calculation of memory request sizes
                                185                 :                :  *
                                186                 :                :  * These functions perform the requested calculation, but throw error if the
                                187                 :                :  * result overflows.
                                188                 :                :  *
                                189                 :                :  * An important property of these functions is that if an argument was a
                                190                 :                :  * negative signed int before promotion (implying overflow in calculating it)
                                191                 :                :  * we will detect that as an error.  That happens because we reject results
                                192                 :                :  * larger than SIZE_MAX / 2.  In the backend we rely on later checks to do
                                193                 :                :  * that, but in frontend we must do it here.
                                194                 :                :  */
                                195                 :                : Size
   19 tgl@sss.pgh.pa.us         196                 :UBC           0 : add_size(Size s1, Size s2)
                                197                 :                : {
                                198                 :                :     Size        result;
                                199                 :                : 
                                200   [ #  #  #  #  :              0 :     if (unlikely(pg_add_size_overflow(s1, s2, &result) ||
                                              #  # ]
                                201                 :                :                  result > (SIZE_MAX / 2)))
                                202                 :              0 :         add_size_error(s1, s2);
                                203                 :              0 :     return result;
                                204                 :                : }
                                205                 :                : 
                                206                 :                : pg_noreturn static pg_noinline void
                                207                 :              0 : add_size_error(Size s1, Size s2)
                                208                 :                : {
                                209                 :              0 :     fprintf(stderr, _("invalid memory allocation request size %zu + %zu\n"),
                                210                 :                :             s1, s2);
                                211                 :              0 :     exit(EXIT_FAILURE);
                                212                 :                : }
                                213                 :                : 
                                214                 :                : Size
                                215                 :              0 : mul_size(Size s1, Size s2)
                                216                 :                : {
                                217                 :                :     Size        result;
                                218                 :                : 
                                219   [ #  #  #  #  :              0 :     if (unlikely(pg_mul_size_overflow(s1, s2, &result) ||
                                              #  # ]
                                220                 :                :                  result > (SIZE_MAX / 2)))
                                221                 :              0 :         mul_size_error(s1, s2);
                                222                 :              0 :     return result;
                                223                 :                : }
                                224                 :                : 
                                225                 :                : pg_noreturn static pg_noinline void
                                226                 :              0 : mul_size_error(Size s1, Size s2)
                                227                 :                : {
                                228                 :              0 :     fprintf(stderr, _("invalid memory allocation request size %zu * %zu\n"),
                                229                 :                :             s1, s2);
                                230                 :              0 :     exit(EXIT_FAILURE);
                                231                 :                : }
                                232                 :                : 
                                233                 :                : /*
                                234                 :                :  * pg_malloc_mul
                                235                 :                :  *      Equivalent to pg_malloc(mul_size(s1, s2)).
                                236                 :                :  */
                                237                 :                : void *
   19 tgl@sss.pgh.pa.us         238                 :CBC     1270613 : pg_malloc_mul(Size s1, Size s2)
                                239                 :                : {
                                240                 :                :     /* inline mul_size() for efficiency */
                                241                 :                :     Size        req;
                                242                 :                : 
                                243   [ +  -  -  +  :        1270613 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              -  + ]
                                244                 :                :                  req > (SIZE_MAX / 2)))
   19 tgl@sss.pgh.pa.us         245                 :UBC           0 :         mul_size_error(s1, s2);
   19 tgl@sss.pgh.pa.us         246                 :CBC     1270613 :     return pg_malloc(req);
                                247                 :                : }
                                248                 :                : 
                                249                 :                : /*
                                250                 :                :  * pg_malloc0_mul
                                251                 :                :  *      Equivalent to pg_malloc0(mul_size(s1, s2)).
                                252                 :                :  *
                                253                 :                :  * This is comparable to standard calloc's behavior.
                                254                 :                :  */
                                255                 :                : void *
   19 tgl@sss.pgh.pa.us         256                 :GBC     1550284 : pg_malloc0_mul(Size s1, Size s2)
                                257                 :                : {
                                258                 :                :     /* inline mul_size() for efficiency */
                                259                 :                :     Size        req;
                                260                 :                : 
                                261   [ +  -  -  +  :        1550284 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              -  + ]
                                262                 :                :                  req > (SIZE_MAX / 2)))
   19 tgl@sss.pgh.pa.us         263                 :UBC           0 :         mul_size_error(s1, s2);
   19 tgl@sss.pgh.pa.us         264                 :GBC     1550284 :     return pg_malloc0(req);
                                265                 :                : }
                                266                 :                : 
                                267                 :                : /*
                                268                 :                :  * pg_malloc_mul_extended
                                269                 :                :  *      Equivalent to pg_malloc_extended(mul_size(s1, s2), flags).
                                270                 :                :  */
                                271                 :                : void *
   19 tgl@sss.pgh.pa.us         272                 :UBC           0 : pg_malloc_mul_extended(Size s1, Size s2, int flags)
                                273                 :                : {
                                274                 :                :     /* inline mul_size() for efficiency */
                                275                 :                :     Size        req;
                                276                 :                : 
                                277   [ #  #  #  #  :              0 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              #  # ]
                                278                 :                :                  req > (SIZE_MAX / 2)))
                                279                 :              0 :         mul_size_error(s1, s2);
                                280                 :              0 :     return pg_malloc_extended(req, flags);
                                281                 :                : }
                                282                 :                : 
                                283                 :                : /*
                                284                 :                :  * pg_realloc_mul
                                285                 :                :  *      Equivalent to pg_realloc(p, mul_size(s1, s2)).
                                286                 :                :  */
                                287                 :                : void *
   19 tgl@sss.pgh.pa.us         288                 :CBC       35770 : pg_realloc_mul(void *p, Size s1, Size s2)
                                289                 :                : {
                                290                 :                :     /* inline mul_size() for efficiency */
                                291                 :                :     Size        req;
                                292                 :                : 
                                293   [ +  -  -  +  :          35770 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              -  + ]
                                294                 :                :                  req > (SIZE_MAX / 2)))
   19 tgl@sss.pgh.pa.us         295                 :UBC           0 :         mul_size_error(s1, s2);
   19 tgl@sss.pgh.pa.us         296                 :CBC       35770 :     return pg_realloc(p, req);
                                297                 :                : }
                                298                 :                : 
                                299                 :                : /*
                                300                 :                :  * palloc_mul
                                301                 :                :  *      Equivalent to palloc(mul_size(s1, s2)).
                                302                 :                :  */
                                303                 :                : void *
                                304                 :           3739 : palloc_mul(Size s1, Size s2)
                                305                 :                : {
                                306                 :                :     /* inline mul_size() for efficiency */
                                307                 :                :     Size        req;
                                308                 :                : 
                                309   [ +  -  -  +  :           3739 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              -  + ]
                                310                 :                :                  req > (SIZE_MAX / 2)))
   19 tgl@sss.pgh.pa.us         311                 :UBC           0 :         mul_size_error(s1, s2);
   19 tgl@sss.pgh.pa.us         312                 :CBC        3739 :     return palloc(req);
                                313                 :                : }
                                314                 :                : 
                                315                 :                : /*
                                316                 :                :  * palloc0_mul
                                317                 :                :  *      Equivalent to palloc0(mul_size(s1, s2)).
                                318                 :                :  *
                                319                 :                :  * This is comparable to standard calloc's behavior.
                                320                 :                :  */
                                321                 :                : void *
   19 tgl@sss.pgh.pa.us         322                 :UBC           0 : palloc0_mul(Size s1, Size s2)
                                323                 :                : {
                                324                 :                :     /* inline mul_size() for efficiency */
                                325                 :                :     Size        req;
                                326                 :                : 
                                327   [ #  #  #  #  :              0 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              #  # ]
                                328                 :                :                  req > (SIZE_MAX / 2)))
                                329                 :              0 :         mul_size_error(s1, s2);
                                330                 :              0 :     return palloc0(req);
                                331                 :                : }
                                332                 :                : 
                                333                 :                : /*
                                334                 :                :  * palloc_mul_extended
                                335                 :                :  *      Equivalent to palloc_extended(mul_size(s1, s2), flags).
                                336                 :                :  */
                                337                 :                : void *
                                338                 :              0 : palloc_mul_extended(Size s1, Size s2, int flags)
                                339                 :                : {
                                340                 :                :     /* inline mul_size() for efficiency */
                                341                 :                :     Size        req;
                                342                 :                : 
                                343   [ #  #  #  #  :              0 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              #  # ]
                                344                 :                :                  req > (SIZE_MAX / 2)))
                                345                 :              0 :         mul_size_error(s1, s2);
                                346                 :              0 :     return palloc_extended(req, flags);
                                347                 :                : }
                                348                 :                : 
                                349                 :                : /*
                                350                 :                :  * repalloc_mul
                                351                 :                :  *      Equivalent to repalloc(p, mul_size(s1, s2)).
                                352                 :                :  */
                                353                 :                : void *
                                354                 :              0 : repalloc_mul(void *p, Size s1, Size s2)
                                355                 :                : {
                                356                 :                :     /* inline mul_size() for efficiency */
                                357                 :                :     Size        req;
                                358                 :                : 
                                359   [ #  #  #  #  :              0 :     if (unlikely(pg_mul_size_overflow(s1, s2, &req) ||
                                              #  # ]
                                360                 :                :                  req > (SIZE_MAX / 2)))
                                361                 :              0 :         mul_size_error(s1, s2);
                                362                 :              0 :     return repalloc(p, req);
                                363                 :                : }
        

Generated by: LCOV version 2.5.0-beta