Skip to content

CTag UInt64 values can serialize without guaranteed 64-bit promotion

Workflow status is tracked in GitHub: https://github.com/emulebb/emulebb/issues/28. This local document is retained as an engineering spec/evidence record.

Closure

Closed locally on 2026-05-24.

  • app commit a59b06d (BUG-118: promote oversized integer tags) makes the integer CTag constructors select TAGTYPE_UINT64 automatically whenever a value exceeds UINT32_MAX, preserving compact TAGTYPE_UINT32 encoding for ordinary values.
  • test commit 9dcb7d7 covers the UINT32_MAX boundary, forced 64-bit tags, and oversized unforced values.

Validation:

  • python -m emule_workspace validate
  • python -m emule_workspace build app --variant main --config Debug --platform x64 --build-output-mode ErrorsOnly
  • python -m emule_workspace build app --variant main --config Release --platform x64 --build-output-mode ErrorsOnly
  • Debug and Release native suites: packets and parity.

Summary

eMuleAI fixed a defensive serialization edge: when a CTag is constructed with an integer value that exceeds uint32, the writer promotes it to a 64-bit tag. Current eMuleBB still relies on caller discipline plus assertions. In release builds, a missed bInt64 caller can therefore serialize truncated metadata or produce protocol-visible inconsistency.

eMuleAI Implementation Reference

Review source: eMuleAI commit 8e34bdec2b7e4fe9e4307df9d80f691804be99ed.

Current Risk

This is not a request to invent new 64-bit wire behavior. eMule already has large-file and 64-bit tag paths. The risk is that a caller with a valid large integer forgets the explicit 64-bit flag and the release build does not enforce what the debug assertion expects.

Intended Fix Shape

Choose one of two narrow approaches:

  • port the eMuleAI auto-promotion guard so impossible uint32 values are serialized as 64-bit tags; or
  • audit every CTag UInt64 construction site and replace implicit caller expectations with explicit helpers that cannot forget 64-bit intent.

The first option is smaller. The second option is stricter but more invasive.

Acceptance Criteria

  • [ ] values above UINT32_MAX cannot be serialized as 32-bit tag payloads by accident
  • [ ] large-file related tags keep current stock-compatible wire semantics
  • [ ] unit or seam tests cover boundary values around UINT32_MAX
  • [ ] no unrelated tag/opcode changes are bundled with this fix