Skip to content

Fix page fault when file size exceeds MaxFileSize - #9

Merged
sclaiborne merged 1 commit into
mainfrom
bugfix/maxfilesize-page-fault
Aug 20, 2026
Merged

Fix page fault when file size exceeds MaxFileSize#9
sclaiborne merged 1 commit into
mainfrom
bugfix/maxfilesize-page-fault

Conversation

@sclaiborne

Copy link
Copy Markdown
Member

Problem

Loading a CSV file at or above IN.CFG.MaxFileSize page-faults the target.

ReadBuffer is allocated at exactly MaxFileSize bytes (csvInitBuffer via CSVFn_Init), but its contents are consumed as a C stringcsvProcessData() runs strtok_r over it. FIOWrap passes IN.PAR.len straight to FileRead with no clamp and no truncation check:

FIOWRAP_ST_READ:
    t.Internal.FUB.Read.len := t.IN.PAR.len;

FileRead has no "bytes actually read" output, so for a file >= MaxFileSize it returns Done with the buffer 100% full and unterminated. Parsing then walks past the end of the TMP_alloc block.

Smaller files worked only by accident — the tail of the buffer was still zeroed by csvClearBuffer, so the bug stayed silent right up to the limit.

The same one-byte hole existed on the write side: csvAddToBuffer accepts data up to exactly MaxLength, so a csvExpandVar fill landing on the limit left ReadBuffer unterminated too.

Fix

  • csvInitBuffer() — allocate BufferLength + 1. MaxLength still holds the usable payload size, so csvAddToBuffer's overflow check and every MaxFileSize semantic are unchanged; the extra byte can only ever hold the terminator. This also closes the csvExpandVar variant.
  • csvClearBuffer() — clear the guard byte as well.
  • CSVFn_Cyclic(), CSV_ST_OPEN — check FIOWrap.OUT.STAT.FileLen against ReadBuffer.MaxLength before touching the data. Oversized files now report CSV_ERR_BUFFERFULL"Maximum file size reached. Check IN.CFG.MaxFileSize." — with ErrorState = CSV_ST_OPEN, instead of parsing truncated data. On the success path, CurrentLength is set from the real file length and the buffer is terminated explicitly rather than relying on leftover zeros.

Behavior change

A file larger than MaxFileSize used to crash the target; it now raises a normal, actionable library error and the state machine goes to CSV_ST_ERROR. Files that fit are unaffected.

Verification

Compiled CSVFileLib through the example project with the AS6 toolchain — the library compiles and links clean. The three csvOpenVar.c -Woverflow / -Wmaybe-uninitialized warnings in the build log are pre-existing and untouched by this change.

Note: the example project pins AR 6.6.2 / OpcUaCs 6.6.1, neither of which is installed on this machine, so the build was run against 6.7.6 / 6.7.0 locally. Those retargets were reverted and are not part of this PR.

🤖 Generated with Claude Code

ReadBuffer was allocated at exactly IN.CFG.MaxFileSize bytes but its
contents are consumed as a C string by strtok_r in csvProcessData().
FIOWrap passes IN.PAR.len straight through to FileRead with no clamp,
so a file at or above MaxFileSize filled the buffer completely, leaving
no terminator. Parsing then ran off the end of the allocation and the
target took a page fault.

- csvInitBuffer(): allocate one extra byte so a completely full buffer
  is still a valid string. MaxLength still holds the usable payload
  length, so all existing overflow checks are unchanged.
- csvClearBuffer(): clear the guard byte as well.
- CSVFn_Cyclic(), CSV_ST_OPEN: compare FIOWrap.OUT.STAT.FileLen against
  ReadBuffer.MaxLength before touching the data. An oversized file now
  reports CSV_ERR_BUFFERFULL ("Maximum file size reached. Check
  IN.CFG.MaxFileSize.") instead of parsing truncated data. On success,
  record CurrentLength and terminate the buffer explicitly rather than
  relying on leftover zeros from the last clear.

Verified by compiling the example project's CSVFileLib against AS6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sclaiborne
sclaiborne merged commit 1186888 into main Aug 20, 2026
1 check passed
@sclaiborne
sclaiborne deleted the bugfix/maxfilesize-page-fault branch August 20, 2026 17:06
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.

1 participant