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

encoding/base32: Stream-based Decoder Might Have a Design Flaw #50754

Closed
ghost opened this issue Jan 22, 2022 · 1 comment
Closed

encoding/base32: Stream-based Decoder Might Have a Design Flaw #50754

ghost opened this issue Jan 22, 2022 · 1 comment

Comments

@ghost
Copy link

ghost commented Jan 22, 2022

Go version: 1.17
OS and architecture: windows/amd64

Consider the following code:

package main

import (
	"bytes"
	"encoding/base32"
	"fmt"
)

func main() {
	foo := "JBSWY===K5XXE3DE"
	bfoo := bytes.NewReader([]byte(foo))

	d := base32.NewDecoder(base32.StdEncoding, bfoo)
	b := make([]byte, 5)
	n, err := d.Read(b)
	fmt.Println(n, err) // 3 <nil> // Extracted from JBSWY===
	n, err = d.Read(b)
	fmt.Println(n, err) // 5 <nil> // Extracted from K5XXE3DE

	d = base32.NewDecoder(base32.StdEncoding, bytes.NewReader([]byte(foo)))
	b = make([]byte, 10) // Now the decode has to read more than the first 8 bytes
	n, err = d.Read(b)
	fmt.Println(n, err) // 0 illegal base32 data at input byte 5

	// As expected
	decb, err := base32.StdEncoding.DecodeString(foo) // [] illegal base32 data at input byte 5
	fmt.Println(decb, err)
}

Shouldn't the second call to Read() return an error, as the decoder already saw the end of base-32-encoding input? Is this a bug, or is this how the decoder has been designed?

I can think of cases where this design might be a bad idea. If your decoder doesn't have enough buffer space (d.buf is 1024 bytes) to store the incoming encoded data (depending on how many bytes the caller asks for) all in one chunk, and therefore processes and returns only a partial chunk, the next chunk is now effectively a disaparate block of encoded input. In this case, even if the input is corrupted (say the first chunk you read ends with padding) the stream-based decoder will not detect it!

The decode, method, which essentially implements Decode(), is aware of this: "decode is like Decode but returns an additional 'end' value, which indicates if end-of-message padding was encountered and thus any additional data is an error."

Am I missing something here, or is the design not proper?

@seankhliao
Copy link
Member

Duplicate of #38657

@seankhliao seankhliao marked this as a duplicate of #38657 Jan 22, 2022
@golang golang locked and limited conversation to collaborators Jan 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants