Skip to content

Fix EPICA CA string truncation#336

Merged
GDYendell merged 1 commit intomainfrom
epics-ca-string-truncation
Mar 13, 2026
Merged

Fix EPICA CA string truncation#336
GDYendell merged 1 commit intomainfrom
epics-ca-string-truncation

Conversation

@GDYendell
Copy link
Contributor

@GDYendell GDYendell commented Mar 12, 2026

This accounts for a null terminator at the end of the string in the record.

Summary by CodeRabbit

  • Bug Fixes
    • Adjusted string length handling so string fields reserve an extra byte for proper formatting and transmission.
  • Tests
    • Updated test expectations to reflect the increased string length in read/write record validations.

@coderabbitai
Copy link

coderabbitai bot commented Mar 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3bb2fb71-6117-4c7b-817f-0272f1c75632

📥 Commits

Reviewing files that changed from the base of the PR and between ba10651 and 68cadb5.

📒 Files selected for processing (2)
  • src/fastcs/transports/epics/ca/util.py
  • tests/transports/epics/ca/test_softioc.py

📝 Walkthrough

Walkthrough

Input and output EPICS CA record builders now add one to string lengths: they use attribute.datatype.length + 1 when a length is present, otherwise DEFAULT_STRING_WAVEFORM_LENGTH + 1. Corresponding tests updated to expect the increased lengths.

Changes

Cohort / File(s) Summary
EPICS CA util
src/fastcs/transports/epics/ca/util.py
Updated _make_in_record and _make_out_record to compute string length as attribute.datatype.length + 1 when provided, or DEFAULT_STRING_WAVEFORM_LENGTH + 1 otherwise.
Tests (softioc)
tests/transports/epics/ca/test_softioc.py
Adjusted parametrized expectations for read and write record creation to reflect increased default and explicit string lengths (e.g., default 256→257, length=10 → 11).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I nibble bytes by moonlight's hum,
One extra hop for strings to come,
A tiny margin, snug and bright,
Records stretch with soft delight,
Hoppity-hop, the fix is done!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix EPICA CA string truncation' is clearly related to and accurately summarizes the main change: adjusting string length calculations to account for null terminators in EPICS CA records.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch epics-ca-string-truncation
📝 Coding Plan for PR comments
  • Generate coding plan

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/fastcs/transports/epics/ca/util.py (1)

247-251: ⚠️ Potential issue | 🟠 Major

Apply the DEFAULT_STRING_WAVEFORM_LENGTH - 1 adjustment to explicit-length strings as well.

The implicit-length case (line 251) correctly accounts for EPICS' NUL terminator by subtracting 1, but the explicit-length case (line 249) does not. In pythonSoftIOC, longStringIn/Out(length=N) sets NELM=N, leaving only N-1 bytes for usable payload. Currently, String(length=3) truncates to 3 characters but the IOC record can only store 2. Change line 249 to return value[: string.length - 1] to keep both paths consistent with the NELM-to-payload semantics.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fastcs/transports/epics/ca/util.py` around lines 247 - 251, In the String
handling branch (the case matching String() as string), adjust the
explicit-length slicing to account for EPICS NUL terminator semantics the same
way the implicit-length path does: replace the current slice using string.length
with one using string.length - 1 so explicit longStringIn/Out(length=N) yields
at most N-1 usable characters; keep the implicit branch using
DEFAULT_STRING_WAVEFORM_LENGTH - 1 unchanged so both paths use NELM-to-payload
semantics consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/fastcs/transports/epics/ca/util.py`:
- Around line 247-251: In the String handling branch (the case matching String()
as string), adjust the explicit-length slicing to account for EPICS NUL
terminator semantics the same way the implicit-length path does: replace the
current slice using string.length with one using string.length - 1 so explicit
longStringIn/Out(length=N) yields at most N-1 usable characters; keep the
implicit branch using DEFAULT_STRING_WAVEFORM_LENGTH - 1 unchanged so both paths
use NELM-to-payload semantics consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9bd23e02-ebe5-4b15-8a9d-9cc0fd5763a6

📥 Commits

Reviewing files that changed from the base of the PR and between afcbf45 and 5282273.

📒 Files selected for processing (2)
  • src/fastcs/transports/epics/ca/util.py
  • tests/transports/epics/ca/test_ca_util.py

@GDYendell GDYendell force-pushed the epics-ca-string-truncation branch 2 times, most recently from 76516a2 to ba10651 Compare March 12, 2026 11:19
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/transports/epics/ca/test_softioc.py (1)

69-76: ⚠️ Potential issue | 🟡 Minor

Cover the remaining string-length branches.

Line 75 now checks the default String() path, but this PR’s production change also affects the String(length=...) branch in _make_in_record and the matching _make_out_record path. As-is, either of those can regress without this suite failing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/transports/epics/ca/test_softioc.py` around lines 69 - 76, Add
parametrize cases to cover the String(length=...) branches so the tests exercise
both _make_in_record and _make_out_record logic for non-default lengths;
specifically add entries using AttrR(String(length=257)) and another for a
shorter length (e.g., 256) with appropriate record_type
("longStringIn"/"longStringOut") and kwargs mirroring the existing case (length,
DESC, initial_value) so the tests assert behavior for the explicit-length path
in _make_in_record and the corresponding _make_out_record handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@tests/transports/epics/ca/test_softioc.py`:
- Around line 69-76: Add parametrize cases to cover the String(length=...)
branches so the tests exercise both _make_in_record and _make_out_record logic
for non-default lengths; specifically add entries using
AttrR(String(length=257)) and another for a shorter length (e.g., 256) with
appropriate record_type ("longStringIn"/"longStringOut") and kwargs mirroring
the existing case (length, DESC, initial_value) so the tests assert behavior for
the explicit-length path in _make_in_record and the corresponding
_make_out_record handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0d2de550-5757-49c8-afd3-b5bae3de5476

📥 Commits

Reviewing files that changed from the base of the PR and between 76516a2 and ba10651.

📒 Files selected for processing (2)
  • src/fastcs/transports/epics/ca/util.py
  • tests/transports/epics/ca/test_softioc.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/fastcs/transports/epics/ca/util.py

This accounts for the null terminator added when storing to the record
@GDYendell GDYendell force-pushed the epics-ca-string-truncation branch from ba10651 to 68cadb5 Compare March 12, 2026 16:13
@GDYendell GDYendell requested a review from shihab-dls March 12, 2026 16:28
@GDYendell GDYendell merged commit 6c1d262 into main Mar 13, 2026
9 checks passed
@GDYendell GDYendell deleted the epics-ca-string-truncation branch March 13, 2026 13:56
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