* Get the data section size of a GRF. * @param f GRF. * @return Size of the data section or SIZE_MAX if the file has no separate data section. */
| 225 | * @return Size of the data section or SIZE_MAX if the file has no separate data section. |
| 226 | */ |
| 227 | size_t GRFGetSizeOfDataSection(FileHandle &f) |
| 228 | { |
| 229 | extern const std::array<uint8_t, 8> _grf_cont_v2_sig; |
| 230 | static const uint header_len = 14; |
| 231 | |
| 232 | uint8_t data[header_len]; |
| 233 | if (fread(data, 1, header_len, f) == header_len) { |
| 234 | if (data[0] == 0 && data[1] == 0 && std::ranges::equal(std::span(data + 2, _grf_cont_v2_sig.size()), _grf_cont_v2_sig)) { |
| 235 | /* Valid container version 2, get data section size. */ |
| 236 | size_t offset = (static_cast<size_t>(data[13]) << 24) | (static_cast<size_t>(data[12]) << 16) | (static_cast<size_t>(data[11]) << 8) | static_cast<size_t>(data[10]); |
| 237 | if (offset >= 1 * 1024 * 1024 * 1024) { |
| 238 | Debug(grf, 0, "Unexpectedly large offset for NewGRF"); |
| 239 | /* Having more than 1 GiB of data is very implausible. Mostly because then |
| 240 | * all pools in OpenTTD are flooded already. Or it's just Action C all over. |
| 241 | * In any case, the offsets to graphics will likely not work either. */ |
| 242 | return SIZE_MAX; |
| 243 | } |
| 244 | return header_len + offset; |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | return SIZE_MAX; |
| 249 | } |
| 250 | |
| 251 | /** |
| 252 | * Calculate the MD5 sum for a GRF, and store it in the config. |
no test coverage detected