Skip to content

Reduce payload size limit from 240 → 64 bytes#2

Merged
petesramek merged 3 commits into
mainfrom
copilot/fix-rawidx-overflow-issue
Mar 21, 2026
Merged

Reduce payload size limit from 240 → 64 bytes#2
petesramek merged 3 commits into
mainfrom
copilot/fix-rawidx-overflow-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 21, 2026

_rawIdx is uint8_t (max 255), but _rawBuf is PLAIN_SIZE + 64 bytes — for large payloads this exceeds 255, making the overflow guard silently unreliable. The fix enforces a 64-byte payload cap: _rawBuf tops out at 133 bytes, comfortably within uint8_t range, closing the bug without any type changes.

64 bytes covers all realistic sensor + control use cases on the target Tiny88 ↔ ESP link while leaving ~310 bytes free RAM per instance on a 512-byte device.

Changes

  • src/TinyLink.h — tighten static_assert limit and update error message:

    // Before
    static_assert(sizeof(T) <= 240, "TinyLink: Payload exceeds 240 bytes (COBS limit).");
    // After
    static_assert(sizeof(T) <= 64, "TinyLink: Payload exceeds 64 bytes. TinyLink is designed for micro-messages.");
  • test/test_protocol.cpp — remove three tests using structs that exceed the new limit (MaxBlock 235 B, Giant 70 B, MaxJump 230 B) and their RUN_TEST registrations; update test_protocol_mtu_limit comment to reflect the 64-byte design ceiling.

  • CHANGELOG.md — add entry under [Unreleased] documenting the limit reduction and the overflow fix it closes.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.registry.nm1.platformio.org
    • Triggering command: /home/REDACTED/.local/bin/pio /home/REDACTED/.local/bin/pio test -e native (dns block)
    • Triggering command: /home/REDACTED/.local/bin/pio /home/REDACTED/.local/bin/pio pkg install --platform native (dns block)
  • api.registry.platformio.org
    • Triggering command: /home/REDACTED/.local/bin/pio /home/REDACTED/.local/bin/pio test -e native (dns block)
    • Triggering command: /home/REDACTED/.local/bin/pio /home/REDACTED/.local/bin/pio pkg install --platform native (dns block)
  • collector.platformio.org
    • Triggering command: /home/REDACTED/.local/bin/pio /home/REDACTED/.local/bin/pio test -e native (dns block)
    • Triggering command: /home/REDACTED/.local/bin/pio /home/REDACTED/.local/bin/pio pkg install --platform native (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

Problem

TinyLink currently allows payload structs up to 240 bytes (sizeof(T) <= 240). This causes a latent bug: _rawIdx is typed as uint8_t (max 255), but _rawBuf is sized as PLAIN_SIZE + 64 bytes. For large payloads, sizeof(_rawBuf) can exceed 255, making the overflow guard if (_rawIdx < sizeof(_rawBuf)) unreliable — _rawIdx wraps around at 255 silently before ever reaching the guard.

Design Decision

TinyLink is designed as a lightweight, micro-message transport layer for resource-constrained devices like the MH-Tiny88 (512 bytes RAM) communicating with ESP boards over UART. Users define their own message structs — TinyLink is a generic skeleton, not opinionated about message content.

A 64-byte payload limit is the right constraint because:

  • It covers all realistic sensor + control use cases (temperature, humidity, pressure, light, sleep commands, status flags, etc.)
  • With sizeof(T) <= 64: PLAIN_SIZE max = 69, _rawBuf max = 133 bytes — well within uint8_t range (255), closing the _rawIdx overflow bug as a side effect, with no type changes needed
  • One TinyLink instance uses ~202 bytes of RAM max, leaving ~310 bytes free on a Tiny88
  • Still genuinely earns the "Tiny" name

Changes Required

src/TinyLink.h

Tighten the existing static_assert in the constructor:

// Before:
static_assert(sizeof(T) <= 240, "TinyLink: Payload exceeds 240 bytes (COBS limit).");

// After:
static_assert(sizeof(T) <= 64, "TinyLink: Payload exceeds 64 bytes. TinyLink is designed for micro-messages.");

test/test_protocol.cpp

The following tests use structs that exceed 64 bytes and must be updated or removed:

  1. test_cobs_max_block_boundary — uses struct MaxBlock { uint8_t raw[235]; } (235 bytes) — remove this test as it tests behavior outside the new design boundary.

  2. test_buffer_headroom_boundary — uses struct Giant { uint8_t raw[70]; } (70 bytes) — remove this test as it exceeds the new 64-byte limit.

  3. test_cobs_max_jump_safety — uses struct MaxJump { uint8_t data[230]; } (230 bytes) — remove this test as it exceeds the new 64-byte limit.

  4. test_protocol_mtu_limit — currently asserts 3 + sizeof(TestPayload) + 2 < 256. Update the comment to reflect the new 64-byte limit. The assert itself can stay as a sanity check but update the comment:

// Before comment: // 3 (Header) + 250 (Payload) + 2 (CRC) = 255
// After comment:  // 3 (Header) + 64 (max Payload) + 2 (CRC) = 69
  1. Remove the removed tests from main() — remove RUN_TEST(test_cobs_max_block_boundary), RUN_TEST(test_buffer_headroom_boundary), and RUN_TEST(test_cobs_max_jump_safety) from the main() test runner.

README.md

Update any mention of the 240-byte payload limit to reflect the new 64-byte limit. Search for "240" in the README and update accordingly.

CHANGELOG.md

Add an entry to the [Unreleased] section:

### Changed
- Payload size limit reduced from 240 bytes to 64 bytes to enforce micro-message design intent and eliminate a latent `_rawIdx` overflow bug on large payloads.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: Hey, I would like you to review the repository and make assessment.

Assistant: Here is a comprehensive assessment of petesramek/tiny-link:


📋 Repository Assessment: petesramek/tiny-link

🏁 Overview

TinyLink is a well-crafted, header-only C++ library (v0.4.0) implementing a lightweight serial communication protocol over UART. It is clearly purpose-built for resource-constrained microcontrollers. The project is in an early but polished state, showing strong engineering fundamentals.


✅ Strengths

🔧 Core Protocol Design

  • COBS + Fletcher-16 is an excellent combination. COBS framing eliminates the need for byte-stuffing, guarantees unambiguous frame boundaries using 0x00, and Fletcher-16 provides far stronger error detection than a plain checksum — detecting both bit-flips and swapped bytes.
  • Zero-heap, zero-copy design is exactly right for 8-bit AVR targets. Static buffers, memcpy into a fixed _data field, and a raw function pointer callback (void(*)(const T&)) keep RAM usage predictable.
  • SFINAE-based adapter validation at compile time (C++11/14 compatible) is a sophisticated, correct approach. It cleanly enforces the adapter contract without C++20 concepts.
  • static_assert guards for payload size (≤ 240 bytes) and alignment (alignof(T) == 1) provide excellent early-error DX.

📦 Architecture & Portability

  • Five platform adapters (Arduino, POSIX, Win32, ESP-IDF, STM32 HAL) make this genuinely multi-platform and hardware-agnostic.
  • The adapter pattern (duck-typed via SFINAE) is clean and extensible — users can write their own adapter with minimal effort.
  • The tinylink namespace prevents collision with other libraries, which is import...

This pull request was created from Copilot chat.


📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.

Copilot AI changed the title [WIP] Fix _rawIdx overflow issue in TinyLink Reduce payload size limit from 240 → 64 bytes Mar 21, 2026
Copilot AI requested a review from petesramek March 21, 2026 11:41
…_` (#4)

* Initial plan

* Guard SFINAE block with #ifndef __AVR__ to fix ATtiny88 CI build

Co-authored-by: petesramek <2333452+petesramek@users.noreply.github.com>
Agent-Logs-Url: https://github.com/petesramek/tiny-link/sessions/c5178801-5f58-4aba-afeb-0100e94e1cbf

* Updated SFINAE validation in TinyLink.h to use std::declval<T>() instead of T() for improved adapter validation.

* Updated test/test_protocol.cpp with changes to tinylink::TYPE_DATA

* Append missing main() function

* Revert "Append missing main() function"

This reverts commit bb18bb0.

* fixed tesst

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: petesramek <2333452+petesramek@users.noreply.github.com>
Co-authored-by: Pete Sramek <me@petesramek.com>
@petesramek petesramek marked this pull request as ready for review March 21, 2026 13:18
@petesramek petesramek merged commit 20b6e50 into main Mar 21, 2026
4 checks passed
@petesramek petesramek deleted the copilot/fix-rawidx-overflow-issue branch March 22, 2026 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants