feat: verify CRC32 checksum for font files (#1904)

## Summary

* **What is the goal of this PR?**  
Add end-to-end integrity verification for downloaded font files by
including CRC32 checksums in the font manifest and validating downloaded
`.cpfont` files on device.

* **What changes are included?**  
- `generate-font-manifest.py`: compute and include `crc32` for each
`.cpfont` asset in the generated `fonts.json` manifest.
- `FontDownloadActivity.h`: extend manifest file metadata with `crc32`
and declare checksum helper.
- `FontDownloadActivity.cpp`: parse `crc32` from manifest, compute CRC32
of downloaded files using `esp_rom_crc32_le`.

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**YES**_
This commit is contained in:
WuTofu
2026-05-09 21:46:59 -05:00
committed by GitHub
parent bf30964982
commit 3efc863038
3 changed files with 63 additions and 0 deletions
@@ -50,6 +50,7 @@ class FontDownloadActivity : public Activity {
struct ManifestFile {
std::string name;
size_t size = 0;
uint32_t crc32 = 0;
};
struct ManifestFamily {
@@ -83,6 +84,7 @@ class FontDownloadActivity : public Activity {
bool fetchAndParseManifest();
void downloadFamily(ManifestFamily& family);
void downloadAll();
static bool computeFileCrc32(const char* path, uint32_t& outCrc);
bool isDownloadAllSelected() const { return selectedIndex_ == 0 && !families_.empty(); }
int familyIndexFromList(int listIndex) const { return listIndex - 1; }
int listItemCount() const { return families_.empty() ? 0 : static_cast<int>(families_.size()) + 1; }