| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * mpq-block.c -- MPQ block-table 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-block.h" | ||
| 21 | #include "mpq-endian.h" | ||
| 22 | #include <libmpq/mpq.h> | ||
| 23 | |||
| 24 | /* Decode base entries without interpreting flags or file positions. */ | ||
| 25 | int32_t | ||
| 26 | 1626 | libmpq__block_table_decode( | |
| 27 | const uint8_t *input, size_t input_size, mpq_block_s *entries, size_t entry_count | ||
| 28 | ) | ||
| 29 | { | ||
| 30 | size_t i; | ||
| 31 | |||
| 32 |
2/2✓ Branch 0 taken 1625 times.
✓ Branch 1 taken 1 times.
|
1626 | if (entry_count > SIZE_MAX / LIBMPQ_BLOCK_ENTRY_WIRE_SIZE || |
| 33 |
4/4✓ Branch 0 taken 1624 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1622 times.
✓ Branch 3 taken 2 times.
|
1625 | input_size < entry_count * LIBMPQ_BLOCK_ENTRY_WIRE_SIZE || |
| 34 |
2/4✓ Branch 0 taken 1622 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1622 times.
|
1622 | (entry_count != 0 && (input == NULL || entries == NULL))) |
| 35 | 2 | return LIBMPQ_ERROR_SIZE; | |
| 36 | |||
| 37 |
2/2✓ Branch 0 taken 116776 times.
✓ Branch 1 taken 1624 times.
|
118400 | for (i = 0; i < entry_count; i++) { |
| 38 | 116776 | const uint8_t *wire = input + i * LIBMPQ_BLOCK_ENTRY_WIRE_SIZE; | |
| 39 | |||
| 40 | 116776 | entries[i].offset = libmpq__load_le32(wire); | |
| 41 | 116776 | entries[i].packed_size = libmpq__load_le32(wire + 4); | |
| 42 | 116776 | entries[i].unpacked_size = libmpq__load_le32(wire + 8); | |
| 43 | 116776 | entries[i].flags = libmpq__load_le32(wire + 12); | |
| 44 | } | ||
| 45 | 1624 | return 0; | |
| 46 | } | ||
| 47 | |||
| 48 | /* Encode base entries into caller-owned bytes before table encryption. */ | ||
| 49 | int32_t | ||
| 50 | 743 | libmpq__block_table_encode( | |
| 51 | const mpq_block_s *entries, size_t entry_count, uint8_t *output, size_t output_size | ||
| 52 | ) | ||
| 53 | { | ||
| 54 | size_t i; | ||
| 55 | |||
| 56 |
2/2✓ Branch 0 taken 742 times.
✓ Branch 1 taken 1 times.
|
743 | if (entry_count > SIZE_MAX / LIBMPQ_BLOCK_ENTRY_WIRE_SIZE || |
| 57 |
4/4✓ Branch 0 taken 741 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 740 times.
✓ Branch 3 taken 1 times.
|
742 | output_size < entry_count * LIBMPQ_BLOCK_ENTRY_WIRE_SIZE || |
| 58 |
2/4✓ Branch 0 taken 740 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 740 times.
|
740 | (entry_count != 0 && (entries == NULL || output == NULL))) |
| 59 | 2 | return LIBMPQ_ERROR_SIZE; | |
| 60 | |||
| 61 |
2/2✓ Branch 0 taken 39914 times.
✓ Branch 1 taken 741 times.
|
40655 | for (i = 0; i < entry_count; i++) { |
| 62 | 39914 | uint8_t *wire = output + i * LIBMPQ_BLOCK_ENTRY_WIRE_SIZE; | |
| 63 | |||
| 64 | 39914 | libmpq__store_le32(wire, entries[i].offset); | |
| 65 | 39914 | libmpq__store_le32(wire + 4, entries[i].packed_size); | |
| 66 | 39914 | libmpq__store_le32(wire + 8, entries[i].unpacked_size); | |
| 67 | 39914 | libmpq__store_le32(wire + 12, entries[i].flags); | |
| 68 | } | ||
| 69 | 741 | return 0; | |
| 70 | } | ||
| 71 | |||
| 72 | /* Decode the optional v2 high-offset words without changing their values. */ | ||
| 73 | int32_t | ||
| 74 | 497 | libmpq__block_ex_table_decode( | |
| 75 | const uint8_t *input, size_t input_size, mpq_block_ex_s *entries, size_t entry_count | ||
| 76 | ) | ||
| 77 | { | ||
| 78 | size_t i; | ||
| 79 | |||
| 80 |
2/2✓ Branch 0 taken 496 times.
✓ Branch 1 taken 1 times.
|
497 | if (entry_count > SIZE_MAX / LIBMPQ_BLOCK_EX_ENTRY_WIRE_SIZE || |
| 81 |
4/4✓ Branch 0 taken 495 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 494 times.
✓ Branch 3 taken 1 times.
|
496 | input_size < entry_count * LIBMPQ_BLOCK_EX_ENTRY_WIRE_SIZE || |
| 82 |
2/4✓ Branch 0 taken 494 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 494 times.
|
494 | (entry_count != 0 && (input == NULL || entries == NULL))) |
| 83 | 2 | return LIBMPQ_ERROR_SIZE; | |
| 84 | |||
| 85 |
2/2✓ Branch 0 taken 54623 times.
✓ Branch 1 taken 495 times.
|
55118 | for (i = 0; i < entry_count; i++) |
| 86 | 54623 | entries[i].offset_high = libmpq__load_le16(input + i * LIBMPQ_BLOCK_EX_ENTRY_WIRE_SIZE); | |
| 87 | 495 | return 0; | |
| 88 | } | ||
| 89 | |||
| 90 | /* Encode the optional v2 high-offset words in little-endian order. */ | ||
| 91 | int32_t | ||
| 92 | 851 | libmpq__block_ex_table_encode( | |
| 93 | const mpq_block_ex_s *entries, size_t entry_count, uint8_t *output, size_t output_size | ||
| 94 | ) | ||
| 95 | { | ||
| 96 | size_t i; | ||
| 97 | |||
| 98 |
2/2✓ Branch 0 taken 850 times.
✓ Branch 1 taken 1 times.
|
851 | if (entry_count > SIZE_MAX / LIBMPQ_BLOCK_EX_ENTRY_WIRE_SIZE || |
| 99 |
4/4✓ Branch 0 taken 849 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 848 times.
✓ Branch 3 taken 1 times.
|
850 | output_size < entry_count * LIBMPQ_BLOCK_EX_ENTRY_WIRE_SIZE || |
| 100 |
2/4✓ Branch 0 taken 848 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 848 times.
|
848 | (entry_count != 0 && (entries == NULL || output == NULL))) |
| 101 | 2 | return LIBMPQ_ERROR_SIZE; | |
| 102 | |||
| 103 |
2/2✓ Branch 0 taken 12864 times.
✓ Branch 1 taken 849 times.
|
13713 | for (i = 0; i < entry_count; i++) |
| 104 | 12864 | libmpq__store_le16(output + i * LIBMPQ_BLOCK_EX_ENTRY_WIRE_SIZE, entries[i].offset_high); | |
| 105 | 849 | return 0; | |
| 106 | } | ||
| 107 |