## Coverage Report

#### Created: 2025-03-01 02:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /libfido2/openbsd-compat/recallocarray.c

    Line
    Count
    Source
    1
    /*      $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $  */
    2
    /*
    3
     * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
    4
     *
    5
     * Permission to use, copy, modify, and distribute this software for any
    6
     * purpose with or without fee is hereby granted, provided that the above
    7
     * copyright notice and this permission notice appear in all copies.
    8
     *
    9
     * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    10
     * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    11
     * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    12
     * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    13
     * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    14
     * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    15
     * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    16
     */
    17
    18
    /* OPENBSD ORIGINAL: lib/libc/stdlib/recallocarray.c */
    19
    20
    #include "openbsd-compat.h"
    21
    22
    #if !defined(HAVE_RECALLOCARRAY)
    23
    24
    #include <errno.h>
    25
    #include <stdlib.h>
    26
    #include <stdint.h>
    27
    #include <string.h>
    28
    #ifdef HAVE_UNISTD_H
    29
    #include <unistd.h>
    30
    #endif
    31
    32
    /*
    33
     * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
    34
     * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
    35
     */
    36
    3.84M
    #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
    37
    38
    void *
    39
    recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
    40
    830k
    {
    41
    830k
            size_t oldsize, newsize;
    42
    830k
            void *newptr;
    43
    44
    830k
            if (ptr == NULL)
    45
    188k
                    return calloc(newnmemb, size);
    46
    47
    641k
            if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
    48
    641k
                newnmemb > 0 && SIZE_MAX / newnmemb < size) {
    49
    0
                    errno = ENOMEM;
    50
    0
                    return NULL;
    51
    0
            }
    52
    641k
            newsize = newnmemb * size;
    53
    54
    641k
            if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
    55
    641k
                oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
    56
    0
                    errno = EINVAL;
    57
    0
                    return NULL;
    58
    0
            }
    59
    641k
            oldsize = oldnmemb * size;
    60
    61
            /*
    62
             * Don't bother too much if we're shrinking just a bit,
    63
             * we do not shrink for series of small steps, oh well.
    64
             */
    65
    641k
            if (newsize <= oldsize) {
    66
    3
                    size_t d = oldsize - newsize;
    67
    68
    3
                    if (d < oldsize / 2 && d < (size_t)getpagesize()) {
    69
    3
                            memset((char *)ptr + newsize, 0, d);
    70
    3
                            return ptr;
    71
    3
                    }
    72
    3
            }
    73
    74
    641k
            newptr = malloc(newsize);
    75
    641k
            if (newptr == NULL)
    76
    1.68k
                    return NULL;
    77
    78
    639k
            if (newsize > oldsize) {
    79
    639k
                    memcpy(newptr, ptr, oldsize);
    80
    639k
                    memset((char *)newptr + oldsize, 0, newsize - oldsize);
    81
    639k
            } else
    82
    0
                    memcpy(newptr, ptr, newsize);
    83
    84
    639k
            explicit_bzero(ptr, oldsize);
    85
    639k
            free(ptr);
    86
    87
    639k
            return newptr;
    88
    641k
    }
    89
    /* DEF_WEAK(recallocarray); */
    90
    91
    #endif /* !defined(HAVE_RECALLOCARRAY) */