Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the inputFile option #656

Closed
ehmicky opened this issue Jan 6, 2024 · 4 comments
Closed

Remove the inputFile option #656

ehmicky opened this issue Jan 6, 2024 · 4 comments

Comments

@ehmicky
Copy link
Collaborator

ehmicky commented Jan 6, 2024

The inputFile option is now redundant with the stdin option.

The inputFile option has one pro: relative file paths do not need to start with .. This is easily fixed by using URLs, absolute file paths (path.resolve()), or directly prepending ./ to the file paths.

However, it has multiple cons:

  • It cannot pipe multiple sources, unlike stdin (for example { stdin: ['./path.txt', 'inherit'] })
  • It supports much fewer types (only file paths)

Having two almost redundant options complicates the API, so I suggest we remove the inputFile option in favor of the stdin option.

Unlike the input option, the inputFile option is a fairly recent feature (from March 2023, release 7.1.0), so it should be a breaking change for only few users.

What do you think @sindresorhus?

@sindresorhus
Copy link
Owner

On one hand, it would be nice to remove the redundancy, on the other hand, it's also kinda annoying that we need the ./ prefix. It's fine when you specify the path statically, but it gets more complicated if you want to just pass in an arbitrary path outside of your control. It could also be a potential security issue. For example, you accept a path as user input and pass it to stdin. Then the user could control pipe, inherit, etc, if the developer is not careful with sanitizing it.

Some potential solutions:

  1. Keep inputFile for this use-case and convenience.
  2. Add a stdinPath() utility that would sanitize it by basically just making it an absolute path. { stdin: [stdinPath(someUserGivenPath), 'inherit'] }
  3. Force using constants for the redirection options. { stdin: ['path.txt', execa.constants.inherit] }
  4. ?

1 seems like the easiest solution to me.

This issue only exists because JS is so weakly typed. In Swift and many other languages, 'inherit' etc would have been an enum.

@ehmicky
Copy link
Collaborator Author

ehmicky commented Jan 8, 2024

Yes, this makes lots of sense. Thanks a lot for sharing this feedback @sindresorhus, that's super helpful!

Other options include:

  1. Only allow file URLs, not file path strings. However, those can be a little awkward to construct, and error-prone. Namely, if the input is dynamic (i.e. might be a Windows file path), one must use pathToFileURL() to make it work on Windows. Also, one must be careful about the base being used (process.cwd() vs import.meta.url). As much as I like the idea of file URLs from the perspective of working in any JavaScript environment, they are definitely slightly harder to construct.
  2. Use a "known" plain object, e.g. { stdin: [{ file: 'path.txt' }, 'inherit'] }

Please note that this issue is not limited to stdin, but impacts stdout and stderr too, so that's a wider issue than the inputFile option.

However, I think it's safe to close this issue when it comes to the inputFile option, since security should be paramount, especially with this library. 👍

@ehmicky ehmicky closed this as completed Jan 8, 2024
@sindresorhus
Copy link
Owner

Use a "known" plain object, e.g. { stdin: [{ file: 'path.txt' }, 'inherit'] }

Maybe we should require this regardless (while still keeping inputFile)? To avoid potential mistakes or users accidentally introducing security issues.

@ehmicky
Copy link
Collaborator Author

ehmicky commented Jan 9, 2024

Yes, this sounds good.
We haven't released this feature yet, so it's a good time to do it.
One upside is that it would remove the restriction with starting with . for relative file paths.

Opened #667 for it.

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

No branches or pull requests

2 participants