Skip to content

Format units longer than 255 bytes in full - #444

Merged
Enchufa2 merged 1 commit into
r-quantities:mainfrom
billdenney:fix-long-unit-format
Sep 28, 2026
Merged

Enchufa2 merged 1 commit into
r-quantities:mainfrom
billdenney:fix-long-unit-format

Conversation

@billdenney

Copy link
Copy Markdown
Contributor

Summary

R_ut_format() formatted units into a 256-byte buffer and warned only when ut_format() returned exactly sizeof(buf). But ut_format() truncates to fit and returns the length it needs. Any unit whose string form was longer than 255 bytes therefore came back silently cut short, and callers re-parsed the truncated string. For a product of about 52 or more user-defined base units, convert_to_base() then failed with syntax error, cannot parse '...' or cannot convert ... into ....

Fix

  • When the buffer is too small, format again into a buffer of the length ut_format() reports.
  • Stop with an error on a negative return instead of returning an unset buffer. That path is currently unreachable, because r_error_fn throws first.
  • Remove the dead == sizeof(buf) warning.

Tests

  • New tests cover formatted lengths of exactly 255, 256 and 257 bytes, and 300 bytes, through both ud_parse() and convert_to_base(). They fail on main and pass with the fix.
  • R CMD check: Status OK; tests 596 pass, 0 fail.

Relationship to #443

Both PRs touch the formatting helper, so whichever lands second merges the other. The conflicts, in src/udunits.cpp, NEWS.md and tests/testthat/test_udunits.R, are mechanical:

  • keep that PR's R_ut_format() and move this retry into its format_unit();
  • keep both NEWS entries and both tests, watching the shared closing }).

A trial merge gives 594 expectations and 0 failures.

🤖 Generated with Claude Code

R_ut_format() formatted into a 256-byte buffer and warned only when
ut_format() returned exactly sizeof(buf). ut_format() truncates to fit and
returns the length it needs, so any unit whose string form is longer than
255 bytes came back silently cut short, and callers re-parsed the stub. For
a product of about 52 or more user-defined base units, convert_to_base()
then failed with "syntax error, cannot parse '...'" or "cannot convert ...
into ...".

When the buffer is too small, format again into one of the length
ut_format() reports. Also stop on a negative return instead of returning
an unset buffer (unreachable while r_error_fn throws first).

Tests cover formatted lengths of exactly 255, 256 and 257 bytes, and 300,
through ud_parse() and through convert_to_base().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Enchufa2
Enchufa2 merged commit 7180a90 into r-quantities:main Sep 28, 2026
14 checks passed
@billdenney
billdenney deleted the fix-long-unit-format branch September 28, 2026 11:09
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