Showmax/env

parsing os.FileMode doesn't check upper boundaries

prochac opened this issue · 5 comments

The parser ignores if parsed value is "overflowing" file mode range.

https://play.golang.org/p/XhOFdvb44WY

It can be used to setup the first column

https://play.golang.org/p/Rho-VxxTVfu

I know about this, but I am not sure if it is an issue. If you look to Go documentation, you will notice that fs.FileMode is an alias to uint32 and the documentation states, that only least nine significant bits represents UNIX permissions. The rest is reserved for file mode bits and can have arbitrary meaning on different systems (as I understand). Thus, IMHO, it is perfectly fine that we do not check for overflow, and that the two permission strings you print in the play.golang.org example are the same.

I am open to discussion. What is your opinion?

Imagine, I have this app what just creates directories.
https://play.golang.org/p/bbN9t0_W8g-
What I want is to create a directory with similar behavior of /tmp. (everybody can add a file, but delete only their own)
So I have to create a directory with sticky bit, chmod +trwx or chmod 1777 on linux to achieve trwxrwxrwx.

The 1777 can't be used, because of the required zero prefix.
If I use "01777" then its parsed as -rwxrwxrwx. The true value is 1023 (0o1777), YES, but it doesn't work as intended, due to Go's internal handling of the value.

But, I can achieve my goal by using 04000777 as environment variable. And I hope you see that this doesn't feel right.

This is not env package related issue, but fs package related issue. We might have our opinion on the fs.FileMode implementation, but we have to kinda accept that. I believe you would agree that the env package cannot have domain knowledge of all possible types in all packages and treat them specially. Moreover, even if it could, the package shouldn't enforce its "strong opinion" on different type parsing. That's up to authors of types to implement proper serialization and deserialization for them.

The fact that env package parses fs.FileMode is mostly an accident (as it's uint32) than an intention. Naturally it parses it in a form which the fs.FileMode uses to represent file permissions. If you want to have a different behaviour, you can write your own type wrapping fs.FileMode and implementing encoding.TextUnmarshaler. This way, you will be able to have your own FileMode parsing exactly as you ask for. There is no need to change the behaviour for everyone else who could expect and even use the current parsing logic. That would be much more ideomatic solution, don't you think?

It's not accident. This PR adds support for os.FileMode.
#7
Partially, it feels like a weird support for octal numbers.
https://play.golang.org/p/mUtAFMIlYQH 😄

But my opinion has changed over the time this issue is open.
What I have expected before is support of Unix permissions. But they are not compatible with other platforms supported by Go.
Let's say I would like to create a temp file on Plan9.
https://pkg.go.dev/io/fs#ModeTemporary

So now the implementation, and configuration interface of imaginary application, is Go specific.
When I would like to do a rewrite of the imaginary app in Rust, I would need to mimic the Go behavior, or change the config interface.

There doesn't seem to be any win-win situation.
I guess the user should decide its way to go.

It's not accident. This PR adds support for os.FileMode.
You are right, sorry I have missed that there is separate parser. I expected it to be parsed as it's uint32.

I mostly agree with you. There is no win-win, as the parsing is platform specific and conventions differ platform per platform. We can in the future discuss the octal number parsing if necessary. I'm still not 100% certain that env package should support this parsing. For me the first choice would be encoding.TextUnmarshaler interface as there I'd be able to implement whichever logic my app needs.