> I'm looking to develop an alternative to an existing piece of code that 
reads email parts into byte slices and then returns these after decoding

Aside: are you actually seeing invalid (unpadded) base64-encoded MIME parts 
in the wild?

Since a padded base64-encoded block will always be a multiple of 4 
characters (excluding whitespace) I guess you could make a reader which 
counts these as it goes; if it sees EOF when N%4 is 2 or 3, it adds 2 or 1 
"=" characters respectively.  (N%4 == 1 can never occur unless the base64 
stream is corrupt).

On Sunday, 12 January 2025 at 18:53:29 UTC Rory Campbell-Lange wrote:

> I'm looking to develop an alternative to an existing piece of code that 
> reads email parts into byte slices and then returns these after decoding.
>
> As library users may not wish to use these email parts and because there a 
> multiple byte slice copies being used, I'm attempting to rationalise the 
> process by simply wrapping the provided io.Reader with the necessary 
> decoders to reduce memory usage and unnecessary processing.
>
> The wrapping strategy seems to work ok. However there is a particular 
> issue in detecting base64.StdEncoding versus base64.RawStdEncoding, which 
> requires draining the io.Reader using base64.StdEncoding and (based on the 
> current implementation) switching to base64.RawStdEncoding if an 
> io.ErrUnexpectedEOF is found.
>
> I'd be grateful for any thoughts on the most efficient way of dealing with 
> this type of issue, avoiding the need for lots of in-memory copies of -- 
> say -- a 50MB email attachment. Unfortunately neither net/mail.Message.Body 
> or mime/multipart.Part, which provide the input to this func, provide 
> ReadSeekers.
>
> Code snippet below.
>
> Thanks!
> Rory
>
>
> // decodeContent wraps the content io.Reader in either a base64 or
> // quoted printable decoder if applicable. It further wraps the reader
> // in a transform character decoder if an encoding is supplied.
> func decodeContent(content io.Reader, e encoding.Encoding, cte 
> ContentTransferEncoding) io.Reader {
>
> var contentReader io.Reader
>
> switch cte {
> case cteBase64:
>
> contentReader = base64.NewDecoder(base64.StdEncoding, content)
> // ideally check for errors.Is(err, io.ErrUnexpectedEOF); switch decoder to
> // contentReader = base64.NewDecoder(base64.RawStdEncoding, content)
>
> case cteQuotedPrintable:
> contentReader = quotedprintable.NewReader(content)
> default:
> contentReader = content
> }
>
> if e == nil {
> return contentReader
> }
> return transform.NewReader(contentReader, e.NewDecoder())
> }
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/ff7ff2f2-8838-4620-a518-f06a95e4e302n%40googlegroups.com.

Reply via email to