Commit 15cf78fe authored by Clara Engler's avatar Clara Engler
Browse files

Merge branch 'misc_string_slices_1' into 'main'

Fix string_slice exceptions outside of netdoc

See merge request !4092
parents 5121c68b 32be1dd8
Loading
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -240,7 +240,6 @@ impl TorAddr {
    }

    /// Get instructions for how to make a stream to this address
    #[allow(clippy::string_slice)] // TODO
    pub(crate) fn into_stream_instructions(
        self,
        cfg: &crate::config::ClientAddrConfig,
@@ -262,7 +261,9 @@ impl TorAddr {
                    .nth(1)
                    .map(|(i, _)| i + 1)
                    .unwrap_or(0);
                let rhs = &onion[rhs..];
                let rhs = onion
                    .get(rhs..)
                    .expect("character index was not a valid index!?");
                let hsid = rhs.parse()?;
                StreamInstructions::Hs {
                    hsid,
@@ -491,9 +492,8 @@ impl IntoTorAddr for &str {
}

impl IntoTorAddr for String {
    #[allow(clippy::string_slice)] // TODO
    fn into_tor_addr(self) -> Result<TorAddr, TorAddrError> {
        self[..].into_tor_addr()
        self.as_str().into_tor_addr()
    }
}

@@ -513,10 +513,9 @@ impl IntoTorAddr for (&str, u16) {
}

impl IntoTorAddr for (String, u16) {
    #[allow(clippy::string_slice)] // TODO
    fn into_tor_addr(self) -> Result<TorAddr, TorAddrError> {
        let (host, port) = self;
        (&host[..], port).into_tor_addr()
        (host.as_str(), port).into_tor_addr()
    }
}

+4 −5
Original line number Diff line number Diff line
@@ -118,15 +118,14 @@ impl GlobalId {
    /// Try to decode and validate `s` as a [`GlobalId`].
    ///
    /// Returns `Ok(None)` if `s` is not tagged as an identifier for a `GlobalId`.
    #[allow(clippy::string_slice)] // TODO
    pub(crate) fn try_decode(key: &MacKey, s: &ObjectId) -> Result<Option<Self>, LookupError> {
        use base64ct::{Base64Unpadded as B64, Encoding};
        if !s.as_ref().starts_with(GlobalId::TAG_CHAR) {
        let Some(remainder) = s.as_ref().strip_prefix(GlobalId::TAG_CHAR) else {
            return Ok(None);
        }
        };
        let mut bytes = [0_u8; Self::ENCODED_LEN];
        let byte_slice = B64::decode(&s.as_ref()[1..], &mut bytes[..])
            .map_err(|_| LookupError::NoObject(s.clone()))?;
        let byte_slice =
            B64::decode(remainder, &mut bytes[..]).map_err(|_| LookupError::NoObject(s.clone()))?;
        Self::try_decode_from_bytes(key, byte_slice)
            .ok_or_else(|| LookupError::NoObject(s.clone()))
            .map(Some)
+1 −2
Original line number Diff line number Diff line
@@ -539,7 +539,6 @@ where

/// Configure a panic handler to send everything to tracing, in addition to our
/// default panic behavior.
#[allow(clippy::string_slice)] // TODO
fn install_panic_handler() {
    // TODO library support: There's a library called `tracing-panic` that
    // provides a hook we could use instead, but that doesn't have backtrace
@@ -556,7 +555,7 @@ fn install_panic_handler() {
        let msg = match panic_info.payload().downcast_ref::<&'static str>() {
            Some(s) => *s,
            None => match panic_info.payload().downcast_ref::<String>() {
                Some(s) => &s[..],
                Some(s) => s.as_str(),
                None => "Box<dyn Any>",
            },
        };
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ use serde::{Deserialize, Serialize};
mod err;
mod flags;
mod impls;
pub mod util;

pub use err::Error;
pub use flags::{Guard, disable_safe_logging, enforce_safe_logging, with_safe_logging_suppressed};
+137 −0
Original line number Diff line number Diff line
//! Helper functions for writing redacted strings.

use std::fmt;

/// Write up to `chars` _characters_ from the start of `input` onto `f`.
///
/// If any characters are removed, replace them with `ellipsis`.
pub fn write_start_redacted(
    f: &mut fmt::Formatter,
    input: &str,
    chars: usize,
    ellipsis: &str,
) -> fmt::Result {
    if let Some((pos, _)) = input.char_indices().nth(chars) {
        let slice = input
            .get(..pos)
            .expect("Mismatched character offset calculation");
        write!(f, "{slice}{ellipsis}")
    } else {
        write!(f, "{input}")
    }
}

/// Write up to `chars`  _characters_ from the end of `input` onto `f`.
///
/// If any characters are removed, replace them with `ellipsis`.
pub fn write_end_redacted(
    f: &mut fmt::Formatter,
    input: &str,
    chars: usize,
    ellipsis: &str,
) -> fmt::Result {
    if chars == 0 {
        if input.is_empty() {
            Ok(())
        } else {
            write!(f, "{ellipsis}")
        }
    } else if let Some((pos, _)) = input.char_indices().nth_back(chars - 1)
        && pos != 0
    {
        let slice = input
            .get(pos..)
            .expect("Mismatched character offset calculation");
        write!(f, "{ellipsis}{slice}")
    } else {
        write!(f, "{input}")
    }
}

#[cfg(test)]
mod test {
    // @@ begin test lint list maintained by maint/add_warning @@
    #![allow(clippy::bool_assert_comparison)]
    #![allow(clippy::clone_on_copy)]
    #![allow(clippy::dbg_macro)]
    #![allow(clippy::mixed_attributes_style)]
    #![allow(clippy::print_stderr)]
    #![allow(clippy::print_stdout)]
    #![allow(clippy::single_char_pattern)]
    #![allow(clippy::unwrap_used)]
    #![allow(clippy::unchecked_time_subtraction)]
    #![allow(clippy::useless_vec)]
    #![allow(clippy::needless_pass_by_value)]
    #![allow(clippy::string_slice)] // See arti#2571
    //! <!-- @@ end test lint list maintained by maint/add_warning @@ -->

    use super::*;

    struct Fmt<'a> {
        string: &'a str,
        n: usize,
        start: bool,
    }

    impl<'a> fmt::Display for Fmt<'a> {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            if self.start {
                write_start_redacted(f, self.string, self.n, "…")
            } else {
                write_end_redacted(f, self.string, self.n, "…")
            }
        }
    }

    fn rstart(string: &str, n: usize) -> String {
        Fmt {
            string,
            n,
            start: true,
        }
        .to_string()
    }

    fn rend(string: &str, n: usize) -> String {
        Fmt {
            string,
            n,
            start: false,
        }
        .to_string()
    }

    #[test]
    fn test_redact_start() {
        assert_eq!(&rstart("hello world", 2), "he…");
        assert_eq!(&rstart("he", 2), "he");
        assert_eq!(&rstart("h", 2), "h");
        assert_eq!(&rstart("", 2), "");

        assert_eq!(&rstart("", 0), "");
        assert_eq!(&rstart("hello", 0), "…");

        assert_eq!(&rstart("分久必合,合久必分", 2), "分久…");
        assert_eq!(&rstart("分久必合,合久必分", 4), "分久必合…");
        assert_eq!(&rstart("分久必合,合久必分", 9), "分久必合,合久必分");
        assert_eq!(&rstart("分久必合,合久必分", 10), "分久必合,合久必分");
        assert_eq!(&rstart("分久必合,合久必分", 0), "…");
    }

    #[test]
    fn test_redact_end() {
        assert_eq!(&rend("hello world", 2), "…ld");
        assert_eq!(&rend("he", 2), "he");
        assert_eq!(&rend("h", 2), "h");
        assert_eq!(&rend("", 2), "");

        assert_eq!(&rend("", 0), "");
        assert_eq!(&rend("hello", 0), "…");

        assert_eq!(&rend("分久必合,合久必分", 2), "…必分");
        assert_eq!(&rend("分久必合,合久必分", 4), "…合久必分");
        assert_eq!(&rend("分久必合,合久必分", 9), "分久必合,合久必分");
        assert_eq!(&rend("分久必合,合久必分", 10), "分久必合,合久必分");
        assert_eq!(&rend("分久必合,合久必分", 0), "…");
    }
}
Loading