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 use of locale-specific strerror_r. #440

Merged
merged 2 commits into from
May 31, 2024

Conversation

briansmith
Copy link
Contributor

strerror_r doesn't necessarily return UTF-8 but we assume it does.

strerror_r is locale-sensitive but we are better off not being locale-sensitive.

strerror_r requires us to use libc but increasingly we want to avoid libc, e.g. to support x86_64-unknown-linux-none.

Just remove the use of the function.

// Take up to trailing null byte
let n = buf.len();
let idx = buf.iter().position(|&b| b == 0).unwrap_or(n);
core::str::from_utf8(&buf[..idx]).ok()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Even if the bytes do not contain any invalid UTF-8 sequences, they might not be encoding UTF-8.

Copy link
Member

Choose a reason for hiding this comment

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

Is there an actual example of this being an issue on a unix target?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No offense, but I don't participate in that kind of thinking. Instead it would be better to have a proof that it isn't an issue.

Copy link
Member

Choose a reason for hiding this comment

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

Oh no offense taken, I think this is a good point (especially when it comes to stuff like the safety of code or cryptographic security where I 100% agree). Sorry for being a little short. I just meant to note that an implementation returning UTF8 bytes that aren't UTF8 only causes the display implementation to show a suboptimal error string.

However, after looking more into strerror_r, I agree that we shouldn't be assuming that it is well behaved on arbitrary unix targets. This is libstd's job, not ours. See my suggestion below.

@josephlr
Copy link
Member

josephlr commented May 30, 2024

I don't think we should remove this. It is quite nice for the Display implementation of an Error to actually print out what the Error means. It doesn't hurt to have it, and if strerror_r happens to return non-UTF8 bytes (which I've never seen happen, but I agree it might be theoretically possible), we just don't print the error string.

Is there a reason not to just use the cfg to exclude targets which don't use libc?

Edit: I think we can actually remove use of stderror_r while still keeping nice descriptions.

@josephlr
Copy link
Member

After looking at this some more (and reading more about stderror_r), I actually think we should remove use of libc::strerror_r here. If std is enabled, we can just use std::io::Error to get a good Debug/Display implementation by doing something like:

impl fmt::Display for Error {
  fn fmt(&self, f: &mut Formatter) {
    if let Some(errno) = self.raw_os_error() {
      #[cfg(feature = "std")]
      std::io::Error::from_raw_os_error(error).fmt(f)
      #[cfg(not(feature = "std"))]
      write!(f, "OS error {}", errno)
    } else {
      ...
    }
  }
}

@newpavlov
Copy link
Member

I agree with the @josephlr's suggestion above.

@briansmith
Copy link
Contributor Author

 #[cfg(feature = "std")]
      std::io::Error::from_raw_os_error(error).fmt(f)

This would mean that the output would depend on the std feature flag. However, this does mean that anything that embeds getrandom::Error in its own structures (errors) will then have its output depend on the std feature flag for getrandom? That seems a bit unfortunate. I personally think less conditional logic is better than avoiding the need to look up the meaning of an error code manually in the extremely rare circumstances anybody needs to do so.

@newpavlov
Copy link
Member

newpavlov commented May 31, 2024

Arguably, the main reason for the Error type existence is improved formatting of user-facing error messages. So I think that improving it with a tiny bit of conditional logic is fine.

strerror_r doesn't necessarily return UTF-8 but we assume it does.

strerror_r is locale-sensitive but we are better off not being
locale-sensitive.

strerror_r requires us to use libc but increasingly we want to
avoid libc, e.g. to support x86_64-unknown-linux-none.

Just remove the use of the function.
Copy link
Member

@josephlr josephlr left a comment

Choose a reason for hiding this comment

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

Thanks for the fix!!

@newpavlov newpavlov merged commit 40e873d into rust-random:master May 31, 2024
52 checks passed
@briansmith briansmith deleted the b/locale branch May 31, 2024 23:24
@newpavlov newpavlov mentioned this pull request Oct 11, 2024
newpavlov added a commit that referenced this pull request Oct 11, 2024
Tweak the breaking changes section and add entries for #415, #440, #442,
#448, #504, and #512.
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.

3 participants