Skip to content

[WIP] Follow-up to #5633: trim filesystem::read buffer to gcount() for text-mode streams#5634

Closed
wnykuang wants to merge 1 commit into
NatLabRockies:developfrom
wnykuang:agent/fix-read-crlf-textmode
Closed

[WIP] Follow-up to #5633: trim filesystem::read buffer to gcount() for text-mode streams#5634
wnykuang wants to merge 1 commit into
NatLabRockies:developfrom
wnykuang:agent/fix-read-crlf-textmode

Conversation

@wnykuang

Copy link
Copy Markdown
Contributor

Pull request overview

Follow-up hardening for #5629 / #5633 — this closes the remaining gap from the same root cause fixed in those PRs.

#5633 fixed read_as_string(const path&) by opening the file in binary mode. However, the underlying read(openstudio::filesystem::ifstream&) helper is still vulnerable when a caller-supplied stream was opened in text mode: it sizes the buffer from the on-disk byte count (seekg/tellg), but on Windows the text-mode CRLF→LF translation makes istream::read() deliver fewer characters than that, leaving a tail of zero-initialized (NUL) bytes in the returned buffer — silently.

There is at least one live path hitting this today: PrjModelImpl.cpp:78 opens ifstream file(path) (text mode) and hands it to contam::Readerread_as_string(ifstream&)read(ifstream&). On Windows, a CONTAM .prj file with CRLF line endings gets the same NUL-padded corruption that broke Filetypes.EpwFile_UTF8BOM.

Fix: after read(), trim the buffer to gcount() — the number of characters actually delivered. Binary-mode reads are unaffected (character count always equals the byte length), so this is a no-op on POSIX and for all existing binary callers.

Verified on Linux by rebuilding openstudio_utilities_tests: the full-suite failure list is byte-identical before/after the change (only pre-existing local environment failures), and all Filetypes.EpwFile* tests pass.

Note: I will follow up on this PR with the related documentation updates required for this project before it is ready for full review.

Pull Request Author

  • Model API Changes / Additions
  • Any new or modified fields have been implemented in the EnergyPlus ForwardTranslator (and ReverseTranslator as appropriate)
  • Model API methods are tested (in src/model/test)
  • EnergyPlus ForwardTranslator Tests (in src/energyplus/Test)
  • If a new object or method, added a test in NREL/OpenStudio-resources: Add Link
  • If needed, added VersionTranslation rules for the objects (src/osversion/VersionTranslator.cpp)
  • Verified that C# bindings built fine on Windows, partial classes used as needed, etc.
  • All new and existing tests passes
  • If methods have been deprecated, update rest of code to use the new methods

Labels:

  • If change to an IDD file, add the label IDDChange
  • If breaking existing API, add the label APIChange
  • If deemed ready, add label Pull Request - Ready for CI so that CI builds your PR

On Windows, ifstreams opened in text mode translate CRLF to LF, so
istream::read() delivers fewer characters than the on-disk length
computed by seeking to the end. The buffer was sized to the on-disk
length and never trimmed, leaving a tail of NUL bytes.

This made read_as_string(path) return corrupted content for any CRLF
file on Windows, which broke the Filetypes.EpwFile_UTF8BOM test
(*.epw resources are checked out with CRLF): the NUL tail parsed as a
garbage 8769th line, failing with 'Insufficient weather data'.

Trim the buffer to gcount() after reading. Binary-mode reads are
unaffected since the character count always matches the byte length.
@wnykuang

Copy link
Copy Markdown
Contributor Author

will double verify the code change in the windows x64; will send doc too.

@wnykuang wnykuang closed this Jul 18, 2026
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