All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Dr. David Alan Gilbert" <dave@treblig.org>
To: Wedson Almeida Filho <wedsonaf@gmail.com>
Cc: ojeda@kernel.org, "Alex Gaynor" <alex.gaynor@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
	patches@lists.linux.dev,
	"Adam Bratschi-Kaye" <ark.email@gmail.com>
Subject: Re: [PATCH v2 20/28] rust: str: add `Formatter` type
Date: Sun, 4 Dec 2022 18:05:21 +0000	[thread overview]
Message-ID: <Y4zhYWNIaGtOH5u6@gallifrey> (raw)
In-Reply-To: <CANeycqrT69HJWEBZwbuhTehSy1qFF7A4q38cb5TqU1yf=nMLOQ@mail.gmail.com>

* Wedson Almeida Filho (wedsonaf@gmail.com) wrote:
> On Sun, 4 Dec 2022 at 15:41, Dr. David Alan Gilbert <dave@treblig.org> wrote:
> >
> > * ojeda@kernel.org (ojeda@kernel.org) wrote:
> > > From: Wedson Almeida Filho <wedsonaf@gmail.com>
> > >
> > > Add the `Formatter` type, which leverages `RawFormatter`,
> > > but fails if callers attempt to write more than will fit
> > > in the buffer.
> > >
> > > In order to so, implement the `RawFormatter::from_buffer()`
> > > constructor as well.
> > >
> > > Co-developed-by: Adam Bratschi-Kaye <ark.email@gmail.com>
> > > Signed-off-by: Adam Bratschi-Kaye <ark.email@gmail.com>
> > > Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com>
> > > Reviewed-by: Gary Guo <gary@garyguo.net>
> > > [Reworded, adapted for upstream and applied latest changes]
> > > Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> > > ---
> > >  rust/kernel/str.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 57 insertions(+)
> > >
> > > diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
> > > index a995db36486f..ce207d1b3d2a 100644
> > > --- a/rust/kernel/str.rs
> > > +++ b/rust/kernel/str.rs
> > > @@ -406,6 +406,23 @@ impl RawFormatter {
> > >          }
> > >      }
> > >
> > > +    /// Creates a new instance of [`RawFormatter`] with the given buffer.
> > > +    ///
> > > +    /// # Safety
> > > +    ///
> > > +    /// The memory region starting at `buf` and extending for `len` bytes must be valid for writes
> > > +    /// for the lifetime of the returned [`RawFormatter`].
> > > +    pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
> > > +        let pos = buf as usize;
> > > +        // INVARIANT: We ensure that `end` is never less then `buf`, and the safety requirements
> > > +        // guarantees that the memory region is valid for writes.
> > > +        Self {
> > > +            pos,
> > > +            beg: pos,
> > > +            end: pos.saturating_add(len),
> > > +        }
> > > +    }
> > > +
> > >      /// Returns the current insert position.
> > >      ///
> > >      /// N.B. It may point to invalid memory.
> > > @@ -439,3 +456,43 @@ impl fmt::Write for RawFormatter {
> > >          Ok(())
> > >      }
> > >  }
> > > +
> > > +/// Allows formatting of [`fmt::Arguments`] into a raw buffer.
> > > +///
> > > +/// Fails if callers attempt to write more than will fit in the buffer.
> > > +pub(crate) struct Formatter(RawFormatter);
> 
> Here we mention that `Formatter` fails if callers attempt to write
> more than will fit in the buffer.
> 
> This is in contrast with `RawFormatter`, which doesn't fail in such
> cases. There's also a comment there explaining it (not visible in this
> patch because it's already there), but I reproduce below:
> 
> /// Allows formatting of [`fmt::Arguments`] into a raw buffer.
> ///
> /// It does not fail if callers write past the end of the buffer so
> that they can calculate the
> /// size required to fit everything.
> ///
> /// # Invariants
> ///
> /// The memory region between `pos` (inclusive) and `end` (exclusive)
> is valid for writes if `pos`
> /// is less than `end`.
> pub(crate) struct RawFormatter {
> 
> `RawFormatter` is used to implement the "%pA" printf specifier, which
> requires this behaviour.
> 
> > > +
> > > +impl Formatter {
> > > +    /// Creates a new instance of [`Formatter`] with the given buffer.
> > > +    ///
> > > +    /// # Safety
> > > +    ///
> > > +    /// The memory region starting at `buf` and extending for `len` bytes must be valid for writes
> > > +    /// for the lifetime of the returned [`Formatter`].
> > > +    #[allow(dead_code)]
> > > +    pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
> > > +        // SAFETY: The safety requirements of this function satisfy those of the callee.
> > > +        Self(unsafe { RawFormatter::from_buffer(buf, len) })
> > > +    }
> > > +}
> > > +
> > > +impl Deref for Formatter {
> > > +    type Target = RawFormatter;
> > > +
> > > +    fn deref(&self) -> &Self::Target {
> > > +        &self.0
> > > +    }
> > > +}
> > > +
> > > +impl fmt::Write for Formatter {
> > > +    fn write_str(&mut self, s: &str) -> fmt::Result {
> > > +        self.0.write_str(s)?;
> > > +
> > > +        // Fail the request if we go past the end of the buffer.
> >
> > Reading this for the first time, I'm surprised by this, perhaps a
> > bit more comment is needed?  I was expecting that nothing would
> > let pos pass end.
> 
> Given the comments I highlight above, do you think we still need more?
> 
> (My impression is that you're reading this without the context I tried
> to explain above, and this context may perhaps be sufficient.)

Thanks for the pointer; I guess I find it trickier when I can't see the
type in self.0 to immediately see it's RawFormatter, and 'Raw' is
abstract enough to need to go hunt to see it's behaviour.

With that context, I wouldn't object to what's there, but how about
something like:

      // RawFormatter (self.0) still updates pos if the buffer
      // is too small, but doesn't fail - we want to fail the request.

Dave

> Thanks,
> -Wedson
-- 
 -----Open up your eyes, open up your mind, open up your code -------   
/ Dr. David Alan Gilbert    |       Running GNU/Linux       | Happy  \ 
\        dave @ treblig.org |                               | In Hex /
 \ _________________________|_____ http://www.treblig.org   |_______/

  reply	other threads:[~2022-12-04 18:05 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-02 16:14 [PATCH v2 00/28] Rust core additions ojeda
2022-12-02 16:14 ` [PATCH v2 01/28] rust: prelude: split re-exports into groups ojeda
2022-12-02 16:14 ` [PATCH v2 02/28] rust: print: add more `pr_*!` levels ojeda
2022-12-02 16:14 ` [PATCH v2 03/28] rust: print: add `pr_cont!` macro ojeda
2022-12-02 16:14 ` [PATCH v2 04/28] rust: samples: add `rust_print` example ojeda
2022-12-02 16:14 ` [PATCH v2 05/28] rust: macros: add `concat_idents!` proc macro ojeda
2022-12-04  0:20   ` Gary Guo
2022-12-02 16:14 ` [PATCH v2 06/28] rust: macros: add `#[vtable]` " ojeda
2022-12-06 12:49   ` Finn Behrens
2022-12-06 15:44     ` Miguel Ojeda
2022-12-02 16:14 ` [PATCH v2 07/28] rust: macros: take string literals in `module!` ojeda
2022-12-02 16:14 ` [PATCH v2 08/28] rust: error: declare errors using macro ojeda
2022-12-02 16:14 ` [PATCH v2 09/28] rust: error: add codes from `errno-base.h` ojeda
2022-12-06 12:52   ` Finn Behrens
2022-12-02 16:14 ` [PATCH v2 10/28] rust: error: add `From` implementations for `Error` ojeda
2022-12-02 16:14 ` [PATCH v2 11/28] rust: prelude: add `error::code::*` constant items ojeda
2022-12-02 16:14 ` [PATCH v2 12/28] rust: alloc: add `RawVec::try_with_capacity_in()` constructor ojeda
2022-12-02 16:14 ` [PATCH v2 13/28] rust: alloc: add `Vec::try_with_capacity{,_in}()` constructors ojeda
2022-12-06 12:55   ` Finn Behrens
2022-12-02 16:14 ` [PATCH v2 14/28] rust: str: add `BStr` type ojeda
2022-12-02 16:14 ` [PATCH v2 15/28] rust: str: add `b_str!` macro ojeda
2022-12-02 16:14 ` [PATCH v2 16/28] rust: str: add `CStr` type ojeda
2022-12-02 16:14 ` [PATCH v2 17/28] rust: str: implement several traits for `CStr` ojeda
2022-12-02 16:14 ` [PATCH v2 18/28] rust: str: add `CStr` unit tests ojeda
2022-12-02 16:14 ` [PATCH v2 19/28] rust: str: add `c_str!` macro ojeda
2022-12-02 16:14 ` [PATCH v2 20/28] rust: str: add `Formatter` type ojeda
2022-12-04 15:41   ` Dr. David Alan Gilbert
2022-12-04 17:26     ` Wedson Almeida Filho
2022-12-04 18:05       ` Dr. David Alan Gilbert [this message]
2022-12-02 16:14 ` [PATCH v2 21/28] rust: str: add `CString` type ojeda
2022-12-02 16:14 ` [PATCH v2 22/28] rust: str: add `fmt!` macro ojeda
2022-12-02 16:14 ` [PATCH v2 23/28] rust: std_vendor: add `dbg!` macro based on `std`'s one ojeda
2022-12-02 16:14 ` [PATCH v2 24/28] rust: static_assert: add `static_assert!` macro ojeda
2022-12-02 16:14 ` [PATCH v2 25/28] rust: add `build_error` crate ojeda
2022-12-02 18:31   ` Wei Liu
2022-12-02 16:14 ` [PATCH v2 26/28] rust: build_assert: add `build_{error,assert}!` macros ojeda
2022-12-02 18:32   ` Wei Liu
2022-12-02 16:14 ` [PATCH v2 27/28] rust: types: add `Either` type ojeda
2022-12-02 23:41   ` Josh Triplett
2022-12-04  0:58     ` Miguel Ojeda
2022-12-04 10:31     ` Gary Guo
2022-12-04 17:36       ` Wedson Almeida Filho
2022-12-05 13:53         ` Miguel Ojeda
2022-12-05 23:00         ` Josh Triplett
2022-12-02 16:14 ` [PATCH v2 28/28] rust: types: add `Opaque` type ojeda
2022-12-04  1:05 ` [PATCH v2 00/28] Rust core additions Miguel Ojeda

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y4zhYWNIaGtOH5u6@gallifrey \
    --to=dave@treblig.org \
    --cc=alex.gaynor@gmail.com \
    --cc=ark.email@gmail.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=gary@garyguo.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=wedsonaf@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.