GCC Code Coverage Report


Directory: src/
File: src/mpq-header.c
Date: 2026-10-06 13:47:41
Exec Total Coverage
Lines: 40 40 100.0%
Functions: 4 4 100.0%
Branches: 16 24 66.7%

Line Branch Exec Source
1 /*
2 * mpq-header.c -- MPQ archive header wire-format encoding and decoding.
3 *
4 * Copyright (c) 2026-2026 Maik Broemme <mbroemme@libmpq.org>
5 *
6 * This file is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
10 *
11 * This file is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this file; if not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "mpq-header.h"
21 #include "mpq-endian.h"
22 #include <libmpq/mpq.h>
23
24 /* Decode only wire fields; archive validation remains with the reader. */
25 int32_t
26 2149 libmpq__header_decode(mpq_header_s *header, const uint8_t *wire, size_t size)
27 {
28
4/6
✓ Branch 0 taken 2149 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2149 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2148 times.
2149 if (header == NULL || wire == NULL || size < LIBMPQ_HEADER_WIRE_SIZE)
29 1 return LIBMPQ_ERROR_SIZE;
30
31 2148 header->mpq_magic = libmpq__load_le32(wire);
32 2148 header->header_size = libmpq__load_le32(wire + 4);
33 2148 header->archive_size = libmpq__load_le32(wire + 8);
34 2148 header->version = libmpq__load_le16(wire + 12);
35 2148 header->block_size = libmpq__load_le16(wire + 14);
36 2148 header->hash_table_offset = libmpq__load_le32(wire + 16);
37 2148 header->block_table_offset = libmpq__load_le32(wire + 20);
38 2148 header->hash_table_count = libmpq__load_le32(wire + 24);
39 2148 header->block_table_count = libmpq__load_le32(wire + 28);
40 2148 return 0;
41 }
42
43 /* Decode the optional version 2 extension from its 12 wire bytes. */
44 int32_t
45 497 libmpq__header_ex_decode(mpq_header_ex_s *header, const uint8_t *wire, size_t size)
46 {
47
4/6
✓ Branch 0 taken 497 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 497 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 496 times.
497 if (header == NULL || wire == NULL || size < LIBMPQ_HEADER_EX_WIRE_SIZE)
48 1 return LIBMPQ_ERROR_SIZE;
49
50 496 header->extended_offset = libmpq__load_le64(wire);
51 496 header->hash_table_offset_high = libmpq__load_le16(wire + 8);
52 496 header->block_table_offset_high = libmpq__load_le16(wire + 10);
53 496 return 0;
54 }
55
56 /* Encode fixed native fields into the exact 32-byte little-endian base header. */
57 int32_t
58 741 libmpq__header_encode(const mpq_header_s *header, uint8_t *wire, size_t size)
59 {
60
4/6
✓ Branch 0 taken 741 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 741 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 740 times.
741 if (header == NULL || wire == NULL || size < LIBMPQ_HEADER_WIRE_SIZE)
61 1 return LIBMPQ_ERROR_SIZE;
62
63 740 libmpq__store_le32(wire, header->mpq_magic);
64 740 libmpq__store_le32(wire + 4, header->header_size);
65 740 libmpq__store_le32(wire + 8, header->archive_size);
66 740 libmpq__store_le16(wire + 12, header->version);
67 740 libmpq__store_le16(wire + 14, header->block_size);
68 740 libmpq__store_le32(wire + 16, header->hash_table_offset);
69 740 libmpq__store_le32(wire + 20, header->block_table_offset);
70 740 libmpq__store_le32(wire + 24, header->hash_table_count);
71 740 libmpq__store_le32(wire + 28, header->block_table_count);
72 740 return 0;
73 }
74
75 /* Encode the optional version 2 extension into exactly 12 wire bytes. */
76 int32_t
77 264 libmpq__header_ex_encode(const mpq_header_ex_s *header, uint8_t *wire, size_t size)
78 {
79
4/6
✓ Branch 0 taken 264 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 264 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 263 times.
264 if (header == NULL || wire == NULL || size < LIBMPQ_HEADER_EX_WIRE_SIZE)
80 1 return LIBMPQ_ERROR_SIZE;
81
82 263 libmpq__store_le64(wire, header->extended_offset);
83 263 libmpq__store_le16(wire + 8, header->hash_table_offset_high);
84 263 libmpq__store_le16(wire + 10, header->block_table_offset_high);
85 263 return 0;
86 }
87