镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

fs streams leak fd on invalid argument #35168

Description

@ronag
// throws and leaks fd
fs.createReadStream(null, {
  fd,
  start: 'invalid argument'
})

Activity

  1. added
    fsIssues and PRs related to file-system APIs and the fs module.
    on Sep 12, 2020
  2. changed the title [-]fs streams don't close fd on invalid argument[/-] [+]fs streams leak fd on invalid argument[/+] on Sep 12, 2020
  3. dylanelliott27 commented on Sep 15, 2020

    @dylanelliott27
    Contributor

    Hi @ronag , I worked out a solution that seems to solve the issue, I just wanted to run my thinking process by you to ensure I am on the right track.

    I am catching the error that is thrown from validateInteger, executing fs.close() on the fd variable passed into the ReadStream/WriteStream constructor, then re-throwing the error that was caught.

    Let me know if my solution here is incorrect or if you have any advice.

    Thanks.

  4. dylanelliott27 commented on Sep 15, 2020

    @dylanelliott27
    Contributor

    @ronag Should I be handling the error from fs.close callback in any specific way? Or should I be using the synchronous method

  5. ronag commented on Sep 15, 2020

    @ronag
    MemberAuthor

    @dylanelliott27 create a PR and we can discuss it there

  6. AasthaGupta commented on Oct 3, 2020

    @AasthaGupta
    Contributor

    @ronag I don't think this is the right problem to be solved at node level but actually, the program using the createReadStream has the fd leak problem. At least considering the snippet you have put in the description.

    I went ahead and checked if we are leaking fd in the case when the path argument is valid and the start argument is invalid. Since in that scenario, the caller has no control over the opened file descriptor. But that's not the case either.

    And here's what I did to confirm that:

    1. Created a file which can't be opened by the user executing the code
    2. Used following code
    const fs = require('fs');
    
    fs.createReadStream("./tmp.txt", {
        start: 'invalid argument'
    })
    

    If the file was being read before argument validation then it would have thrown permission denied, but the test code threw the "Invalid argument" error.

    Hence we can conclude that node is not leaking fd.

  7. ronag commented on Oct 4, 2020

    @ronag
    MemberAuthor

    I don't quite follow...

    Hence we can conclude that node is not leaking fd.

    It is leaking a fd since fs.close is never invoked on the fd if the ReadStream constructor throws. My example is when passing an explicit fd.

  8. targos commented on Oct 11, 2020

    @targos
    Member

    @ronag There's nothing special about createReadStream. All fs methods that accept a file descriptor do not close it when they throw because of bad arguments. For example fs.write(fd, {wrong: 'object'}) also "leaks" fd.

  9. ronag commented on Oct 11, 2020

    @ronag
    MemberAuthor

    @ronag There's nothing special about createReadStream.

    There is something special... streams take ownership of the fd and closes it, while e.g. fs.write does not.

  10. ronag commented on Oct 11, 2020

    @ronag
    MemberAuthor

    You could argue either way in regards to what to expect in this specific case. I think it's cleaner if it closes it otherwise you always should wrap createReadStream/createWriteStream into a try/catch with fs.close, which most users simply won't do. Regardless assumptions should preferably be documented.

  11. targos commented on Oct 11, 2020

    @targos
    Member

    you always should wrap createReadStream/createWriteStream into a try/catch with fs.close

    Not necessarily. You are not supposed to pass invalid arguments to createReadStream in the first place. This is a programming error and the reason why asynchronous functions in Node.js can throw synchronous errors in that case. The solution here is to call createReadStream correctly, not to wrap it into a try/catch.

  12. ronag commented on Oct 11, 2020

    @ronag
    MemberAuthor

    Hm, fair enough.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    fsIssues and PRs related to file-system APIs and the fs module.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions