Skip to content

fs: return Buffer from mkdtemp when prefix is a Buffer#64397

Open
hamidrezaghavami wants to merge 2 commits into
nodejs:mainfrom
hamidrezaghavami:fix-fs-mkdtemp-buffer
Open

fs: return Buffer from mkdtemp when prefix is a Buffer#64397
hamidrezaghavami wants to merge 2 commits into
nodejs:mainfrom
hamidrezaghavami:fix-fs-mkdtemp-buffer

Conversation

@hamidrezaghavami

Copy link
Copy Markdown
Contributor

This PR fixes an issue where passing a Buffer as the prefix to the fs.mkdtemp family of functions incorrectly returned a string, which could mangle non-UTF8 paths.

The options encoding is now safely forced to 'buffer' when a Buffer prefix is detected for both the asynchronous, synchronous, and disposable versions.

Fixes: #58795

@nodejs-github-bot nodejs-github-bot added fs Issues and PRs related to the fs subsystem / file system. needs-ci PRs that need a full CI run. labels Jul 9, 2026
@bakkot

bakkot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks!

  • Should be BufferIsBuffer not Buffer.isBuffer
  • Can't mutate the options object; you'll need to do options = { ...options, encoding: buffer } or something
  • Needs tests
  • Possibly it should be an error if encoding is explicitly specified (and not buffer)?

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.23%. Comparing base (8a3b11c) to head (f30698f).

Files with missing lines Patch % Lines
lib/internal/fs/promises.js 50.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #64397      +/-   ##
==========================================
- Coverage   90.24%   90.23%   -0.02%     
==========================================
  Files         741      741              
  Lines      241384   241393       +9     
  Branches    45480    45492      +12     
==========================================
- Hits       217844   217823      -21     
- Misses      15097    15128      +31     
+ Partials     8443     8442       -1     
Files with missing lines Coverage Δ
lib/fs.js 98.36% <100.00%> (+<0.01%) ⬆️
lib/internal/fs/promises.js 92.69% <50.00%> (-0.13%) ⬇️

... and 38 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Renegade334 Renegade334 added the semver-major PRs that contain breaking changes and should be released in the next major version. label Jul 9, 2026
@hamidrezaghavami hamidrezaghavami force-pushed the fix-fs-mkdtemp-buffer branch 4 times, most recently from 40f2ae2 to 3e3da50 Compare July 10, 2026 10:27
@hamidrezaghavami

Copy link
Copy Markdown
Contributor Author

@bakkot The CI is green! Here is a quick update:

Buffer check: Switched to using the internal BufferIsBuffer.
Immutability: Fixed the code to avoid mutating the user's options object.
Regression test: Added a full test suite for the Buffer prefix (test-fs-mkdtemp-buffer.js).
Original tests: Patched a string coercion bug in the original test-fs-mkdtemp.js file that was crashing the CI.

Let me know if there is anything else I need to adjust!

fs.mkdtemp(Buffer.from(tmpdir.resolve('bar.')), {}, common.mustCall(handler));

// Warning fires only once
fs.mkdtemp(Buffer.from(tmpdir.resolve('bar.X')), common.mustCall(handler));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What happened to these tests?

@bakkot

bakkot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

I'm not a maintainer but the new tests look good, thanks.

Still not sure about, should it be an error if encoding is explicitly specified and not buffer. I don't know if this comes up anywhere else; if so we could look at what the established pattern is. If there isn't an established pattern I would be inclined to throw here.

@hamidrezaghavami hamidrezaghavami requested a review from a team as a code owner July 10, 2026 16:49
@hamidrezaghavami

Copy link
Copy Markdown
Contributor Author

My mistake! I accidentally deleted them while fixing the string coercion bug above. Just restored them in the latest push.

@hamidrezaghavami hamidrezaghavami force-pushed the fix-fs-mkdtemp-buffer branch 3 times, most recently from a3b52bb to f06208f Compare July 10, 2026 18:32
@hamidrezaghavami

hamidrezaghavami commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

@nodejs/collaborators All JavaScript changes and tests are perfectly clean locally!
However, I am getting a format-cpp and lint-js-and-md error from the recent upstream merge conflict on SECURITY.md and node_trace_buffer.h. Could a maintainer please help run the formatters for me since I don't have the local C++ tooling installed? (Also, test-internet appears to be a flaky failure).
Ready for your final review!

@Renegade334

Copy link
Copy Markdown
Member

Please do not add merge commits, it breaks the tooling.

https://github.com/nodejs/node/blob/main/doc/contributing/pull-requests.md#step-5-rebase

Signed-off-by: Hamid Reza Ghavami <hamidr.ghavami@gmail.com>
@aduh95 aduh95 force-pushed the fix-fs-mkdtemp-buffer branch from e4ebc2b to 40fba96 Compare July 11, 2026 11:33
@aduh95 aduh95 removed the request for review from a team July 11, 2026 11:35
@hamidrezaghavami

Copy link
Copy Markdown
Contributor Author

Thank you so much @aduh95 for stepping in and pushing that final fix—you are a lifesaver! 🙏 All 31 checks are completely green now! 🚀
@Renegade334 Since the CI checks have all passed, could either of you please give this a final approving review whenever you have a moment? Ready to merge!

@Renegade334

Copy link
Copy Markdown
Member

Looks like a response is outstanding to #64397 (comment)

@hamidrezaghavami

Copy link
Copy Markdown
Contributor Author

@Renegade334 Thanks for pointing that out! Since bakkot mentioned he isn't a core maintainer, I wasn't sure if his question was a required change or just a general discussion, especially since @aduh95 already reviewed and force-pushed the final code today. Could you clarify if there is still anything specific you would like me to change, or are we good to go? 🙏

@bakkot

bakkot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@hamidrezaghavami The link goes to my comment about deleted tests, not my question about an error. You said you'd restored the deleted tests but I think that got lost in your rebase. Those tests are still missing and you should presumably put them back.

@hamidrezaghavami

Copy link
Copy Markdown
Contributor Author

@bakkot Looks like @aduh95 already restored those missing tests when they force-pushed the branch earlier today! Everything is back in place now. 🙏

@bakkot

bakkot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

No, they're still missing.

@hamidrezaghavami

Copy link
Copy Markdown
Contributor Author

@bakkot Good catch! Ah, they were sitting unsaved in my local editor when I checked earlier. I just pushed commit f30698f restoring all three missing async buffer tests (bar., options object, and bar. X). All CI checks are green again! 🙏

@Renegade334 Renegade334 added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Jul 11, 2026
@Renegade334 Renegade334 removed request-ci Add this label to start a Jenkins CI on a PR. author ready PRs that have at least one approval, no pending requests for changes, and a CI started. labels Jul 11, 2026
@Renegade334

Renegade334 commented Jul 11, 2026

Copy link
Copy Markdown
Member

Implementation is good, but the associated API documentation (doc/api/fs.md) needs updating with this PR.

For example, for fs.mkdtemp():

  • the type of the callback's directory parameter should be changed from {string} to {string|Buffer}
  • the text describing the return behaviour should be changed from
     The created directory path is passed as a string to the callback's second
     parameter.
    to something like
    The created directory path is passed to the callback's second parameter.
    If `prefix` is a `Buffer`, then the resulting directory path is passed as a
    `Buffer`. Otherwise, the path is passed as a string using the specified
    encoding.
  • a changes entry should be added to the YAML block in the method header, along the lines of
    - version: REPLACEME
      pr-url: https://github.com/nodejs/node/pull/64397
      description: The resulting path is now passed as a Buffer
                   if the provided prefix is a Buffer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. fs Issues and PRs related to the fs subsystem / file system. needs-ci PRs that need a full CI run. semver-major PRs that contain breaking changes and should be released in the next major version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fs.mkdtemp should return a Buffer when prefix argument is a Buffer

4 participants