Skip to content

fs functions: Support file positions and sizes above 2 GB - #404

Open
PTR-inc wants to merge 1 commit into
Ylianst:masterfrom
PTR-inc:fs-2g-limit
Open

fs functions: Support file positions and sizes above 2 GB#404
PTR-inc wants to merge 1 commit into
Ylianst:masterfrom
PTR-inc:fs-2g-limit

Conversation

@PTR-inc

@PTR-inc PTR-inc commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

readSync, fs.read, write, writeSync and createReadStream held the position in a 32-bit int, so anything past 2 GB silently did nothing.

Add Duktape_GetInt64PropertyValue() for the 64-bit property, and 64-bit seeks. Duktape_GetIntPropertyValue() uses it too, fixing NaN, which returned 0 rather than the defaultValue.

readFileSync() now refuses a file too large for a Duktape buffer instead of a truncating cast, returns the bytes actually read, and runs under duk_safe_call so the FILE* is closed when it throws.

Built with -D_FILE_OFFSET_BITS=64 so off_t and struct stat are 64-bit on 32-bit targets.

Also the dynamic buffer for readFileSync() now grows to 8MB increments instead of the 1024 bytes to reduce the amount of re-allocations.

Please follow this checklist to avoid unnecessary back and forth (click to expand)
  • 🧠 I used LLMs/AI in this contribution and reviewed all generated content.
    I understand that I am responsible for and able to explain every line of code I submit.
  • 🛠️ I have self-reviewed my code and self-tested it against a MeshCentral server to ensure it works as expected.
  • 🖥️ My change compiles on every platform it affects (Windows / Linux / macOS / FreeBSD), and I have considered
    the impact on platforms and architectures I could not test.
  • 📦 If I changed JavaScript modules under modules/, I re-embedded them so the compiled-in copies in
    microscript/ILibDuktape_Polyfills.c match (the agent runs the embedded copies, not the files on disk).
  • 🤖 I ran the agent self-test where appropriate (see "Self Test" in readme.md).
  • 📄 Documentation updates are included (if applicable), e.g. the .msh options table in readme.md.
  • 🧰 Updates to vendored dependencies (OpenSSL, zlib, ...) are listed and explained.
  • ⚠️ CI passes and is green (Windows / Linux / macOS / FreeBSD builds and CodeQL).

Testing

Tested on mac arm64/x64, linux x86/x64 and windows x86/x64

readSync, fs.read, write, writeSync and createReadStream held the position in a
32-bit int, so anything past 2 GB silently did nothing.

Add Duktape_GetInt64PropertyValue() for the 64-bit property, and 64-bit seeks.
Duktape_GetIntPropertyValue() uses it too, fixing NaN, which returned 0 rather than the defaultValue.

readFileSync() now refuses a file too large for a Duktape buffer instead of a truncating cast,
returns the bytes actually read, and runs under duk_safe_call so the FILE* is closed when it throws.

Built with -D_FILE_OFFSET_BITS=64 so off_t and struct stat are 64-bit on 32-bit targets.

Also the dynamic buffer for readFileSync() now grows to 8MB increments instead of the 1024 bytes
to reduce the amount of re-allocations.
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