extern void lzma_check_finish(lzma_check_state *check, lzma_check type) { switch (type) { #ifdef HAVE_CHECK_CRC32 case LZMA_CHECK_CRC32: check->buffer.u32[0] = conv32le(check->state.crc32); break; #endif #ifdef HAVE_CHECK_CRC64 case LZMA_CHECK_CRC64: check->buffer.u64[0] = conv64le(check->state.crc64); break; #endif #ifdef HAVE_CHECK_SHA256 case LZMA_CHECK_SHA256: lzma_sha256_finish(check); break; #endif default: break; } return; }
/// \brief Parse the Check field and put it into check_value[] /// /// \return False on success, true on error. static bool parse_check_value(file_pair *pair, const lzma_index_iter *iter) { // Don't read anything from the file if there is no integrity Check. if (iter->stream.flags->check == LZMA_CHECK_NONE) { snprintf(check_value, sizeof(check_value), "---"); return false; } // Locate and read the Check field. const uint32_t size = lzma_check_size(iter->stream.flags->check); const off_t offset = iter->block.compressed_file_offset + iter->block.total_size - size; io_buf buf; if (io_pread(pair, &buf, size, offset)) return true; // CRC32 and CRC64 are in little endian. Guess that all the future // 32-bit and 64-bit Check values are little endian too. It shouldn't // be a too big problem if this guess is wrong. if (size == 4) snprintf(check_value, sizeof(check_value), "%08" PRIx32, conv32le(buf.u32[0])); else if (size == 8) snprintf(check_value, sizeof(check_value), "%016" PRIx64, conv64le(buf.u64[0])); else for (size_t i = 0; i < size; ++i) snprintf(check_value + i * 2, 3, "%02x", buf.u8[i]); return false; }