Coverage Report

Created: 2025-12-08 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5Zfletcher32.c
Line
Count
Source
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
#include "H5Zmodule.h" /* This source code file is part of the H5Z module */
14
15
#include "H5private.h"   /* Generic Functions     */
16
#include "H5Eprivate.h"  /* Error handling        */
17
#include "H5MMprivate.h" /* Memory management     */
18
#include "H5Zpkg.h"      /* Data filters        */
19
20
/* Local function prototypes */
21
static size_t H5Z__filter_fletcher32(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
22
                                     size_t nbytes, size_t *buf_size, void **buf);
23
24
/* This message derives from H5Z */
25
const H5Z_class2_t H5Z_FLETCHER32[1] = {{
26
    H5Z_CLASS_T_VERS,       /* H5Z_class_t version */
27
    H5Z_FILTER_FLETCHER32,  /* Filter id number   */
28
    1,                      /* encoder_present flag (set to true) */
29
    1,                      /* decoder_present flag (set to true) */
30
    "fletcher32",           /* Filter name for debugging  */
31
    NULL,                   /* The "can apply" callback     */
32
    NULL,                   /* The "set local" callback     */
33
    H5Z__filter_fletcher32, /* The actual filter function */
34
}};
35
36
0
#define FLETCHER_LEN 4
37
38
/*-------------------------------------------------------------------------
39
 * Function:  H5Z__filter_fletcher32
40
 *
41
 * Purpose: Implement an I/O filter of Fletcher32 Checksum
42
 *
43
 * Return:  Success: Size of buffer filtered
44
 *    Failure: 0
45
 *
46
 *-------------------------------------------------------------------------
47
 */
48
static size_t
49
H5Z__filter_fletcher32(unsigned flags, size_t H5_ATTR_UNUSED cd_nelmts,
50
                       const unsigned H5_ATTR_UNUSED cd_values[], size_t nbytes, size_t *buf_size, void **buf)
51
0
{
52
0
    void          *outbuf = NULL; /* Pointer to new buffer */
53
0
    unsigned char *src    = (unsigned char *)(*buf);
54
0
    uint32_t       fletcher;          /* Checksum value */
55
0
    uint32_t       reversed_fletcher; /* Possible wrong checksum value */
56
0
    uint8_t        c[4];
57
0
    uint8_t        tmp;
58
0
    size_t         ret_value = 0; /* Return value */
59
60
0
    FUNC_ENTER_PACKAGE
61
62
0
    assert(sizeof(uint32_t) >= 4);
63
64
0
    if (flags & H5Z_FLAG_REVERSE) { /* Read */
65
        /* Do checksum if it's enabled for read; otherwise skip it
66
         * to save performance. */
67
0
        if (!(flags & H5Z_FLAG_SKIP_EDC)) {
68
0
            unsigned char *tmp_src;             /* Pointer to checksum in buffer */
69
0
            size_t         src_nbytes = nbytes; /* Original number of bytes */
70
0
            uint32_t       stored_fletcher;     /* Stored checksum value */
71
72
            /* Get the stored checksum */
73
0
            src_nbytes -= FLETCHER_LEN;
74
0
            tmp_src = src + src_nbytes;
75
0
            UINT32DECODE(tmp_src, stored_fletcher);
76
77
            /* Compute checksum (can't fail) */
78
0
            fletcher = H5_checksum_fletcher32(src, src_nbytes);
79
80
            /* The reversed checksum.  There was a bug in the calculating code of
81
             * the Fletcher32 checksum in the library before v1.6.3.  The checksum
82
             * value wasn't consistent between big-endian and little-endian systems.
83
             * This bug was fixed in Release 1.6.3.  However, after fixing the bug,
84
             * the checksum value is no longer the same as before on little-endian
85
             * system.  We'll check both the correct checksum and the wrong
86
             * checksum to be consistent with Release 1.6.2 and before.
87
             */
88
0
            H5MM_memcpy(c, &fletcher, (size_t)4);
89
90
0
            tmp  = c[1];
91
0
            c[1] = c[0];
92
0
            c[0] = tmp;
93
94
0
            tmp  = c[3];
95
0
            c[3] = c[2];
96
0
            c[2] = tmp;
97
98
0
            H5MM_memcpy(&reversed_fletcher, c, (size_t)4);
99
100
            /* Verify computed checksum matches stored checksum */
101
0
            if (stored_fletcher != fletcher && stored_fletcher != reversed_fletcher)
102
0
                HGOTO_ERROR(H5E_STORAGE, H5E_READERROR, 0, "data error detected by Fletcher32 checksum");
103
0
        }
104
105
        /* Set return values */
106
        /* (Reuse the input buffer, just note that the size is smaller by the size of the checksum) */
107
0
        ret_value = nbytes - FLETCHER_LEN;
108
0
    }
109
0
    else {                  /* Write */
110
0
        unsigned char *dst; /* Temporary pointer to destination buffer */
111
112
        /* Compute checksum (can't fail) */
113
0
        fletcher = H5_checksum_fletcher32(src, nbytes);
114
115
0
        if (NULL == (outbuf = H5MM_malloc(nbytes + FLETCHER_LEN)))
116
0
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0,
117
0
                        "unable to allocate Fletcher32 checksum destination buffer");
118
119
0
        dst = (unsigned char *)outbuf;
120
121
        /* Copy raw data */
122
0
        H5MM_memcpy((void *)dst, (void *)(*buf), nbytes);
123
124
        /* Append checksum to raw data for storage */
125
0
        dst += nbytes;
126
0
        UINT32ENCODE(dst, fletcher);
127
128
        /* Free input buffer */
129
0
        H5MM_xfree(*buf);
130
131
        /* Set return values */
132
0
        *buf_size = nbytes + FLETCHER_LEN;
133
0
        *buf      = outbuf;
134
0
        outbuf    = NULL;
135
0
        ret_value = *buf_size;
136
0
    }
137
138
0
done:
139
0
    if (outbuf)
140
0
        H5MM_xfree(outbuf);
141
0
    FUNC_LEAVE_NOAPI(ret_value)
142
0
}