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

Fix and simplify output file permission copying code #578

Merged
merged 1 commit into from
Nov 15, 2023

Conversation

AlexTMjugador
Copy link
Collaborator

@AlexTMjugador AlexTMjugador commented Nov 15, 2023

A detailed read to the Rust documentation for the fs::Permissions struct and a little digging into its implementation in the standard library have shown that this code didn't work as expected in any platform, and was a bit weird to begin with:

  • It first read the permissions from the input file metadata.
  • Then it fetched the output file metadata.
  • After that, it changed the permissions for that output file metadata.
  • It then performed a sanity check that the output file had the expected permissions.

Barring the fact that the sanity check in step 4 is not needed, the overall approach is wrong because setting the permissions in a file metadata struct does not actually persist those changes anywere; it's just an in-memory change only, so these operations were useless. The Rust documentation explicitly mentions that the set_readonly method "does not modify the files attributes" [sic], but it's easy to miss that warning and not realize that it also applies to the methods offered by the PermissionsExt trait. The code only appeared to work because in most cases the default permissions for new files happen to match the input file permissions, so the sanity check passed.

To fix this, use the set_permissions method on File to actually set the output file permissions to be the same as the input file permissions, which is both much simpler and robust.

These changes were tested in the context of issue #576, and fix #576.

A detailed read to the [Rust documentation for the `fs::Permissions`
struct](https://doc.rust-lang.org/stable/std/fs/struct.Permissions.html)
and a little digging into its implementation in the standard library
shown that this code didn't work as expected in any platform, and was a
bit weird to begin with:

- It first read the permissions from the input file metadata.
- Then it fetched the output file metadata.
- After that, it changed the permissions for that output file metadata.
- It then performed a sanity check that the output file had the expected
  permissions.

Barring the fact that the sanity check in step 4 is not needed, the
overall approach is wrong because setting the permissions in a file
metadata struct does not actually persist those changes anywere; it's
just an in-memory change only, so these operations were useless. The
Rust documentation explicitly mentions that the `set_readonly` method
"does not modify the files attributes" [sic], but it's easy to miss that
warning and not realize that it also applies to the methods offered by
the `PermissionsExt` trait. The code only appeared to work because in
most cases the default permissions for new files happen to match the
input file permissions, so the sanity check passed.

To fix this, use the `set_permissions` method on `File` to actually set
the output file permissions to be the same as the input file
permissions, which is both much simpler and robust.

These changes were tested in the context of issue #576, and fix #576.
Copy link
Collaborator

@andrews05 andrews05 left a comment

Choose a reason for hiding this comment

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

Nice work! This makes much more sense and is a lot tidier :)

@AlexTMjugador
Copy link
Collaborator Author

Thank you both, merging this then!

@AlexTMjugador AlexTMjugador merged commit a6152b0 into master Nov 15, 2023
13 checks passed
@AlexTMjugador AlexTMjugador deleted the fix/output-file-permission-copy branch November 15, 2023 23:15
Pr0methean pushed a commit to Pr0methean/oxipng that referenced this pull request Dec 1, 2023
A detailed read to the [Rust documentation for the `fs::Permissions`
struct](https://doc.rust-lang.org/stable/std/fs/struct.Permissions.html)
and a little digging into its implementation in the standard library
have shown that this code didn't work as expected in any platform, and
was a bit weird to begin with:

- It first read the permissions from the input file metadata.
- Then it fetched the output file metadata.
- After that, it changed the permissions for that output file metadata.
- It then performed a sanity check that the output file had the expected
permissions.

Barring the fact that the sanity check in step 4 is not needed, the
overall approach is wrong because setting the permissions in a file
metadata struct does not actually persist those changes anywere; it's
just an in-memory change only, so these operations were useless. The
Rust documentation explicitly mentions that the `set_readonly` method
"does not modify the files attributes" [sic], but it's easy to miss that
warning and not realize that it also applies to the methods offered by
the `PermissionsExt` trait. The code only appeared to work because in
most cases the default permissions for new files happen to match the
input file permissions, so the sanity check passed.

To fix this, use the `set_permissions` method on `File` to actually set
the output file permissions to be the same as the input file
permissions, which is both much simpler and robust.

These changes were tested in the context of issue shssoichiro#576, and fix shssoichiro#576.
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.

2 participants