func (this *ChunkReader) Read() (*alloc.Buffer, error) { buffer := alloc.NewLargeBuffer() if _, err := io.ReadFull(this.reader, buffer.Value[:2]); err != nil { alloc.Release(buffer) return nil, err } // There is a potential buffer overflow here. Large buffer is 64K bytes, // while uin16 + 10 will be more than that length := serial.BytesLiteral(buffer.Value[:2]).Uint16Value() + AuthSize if _, err := io.ReadFull(this.reader, buffer.Value[:length]); err != nil { alloc.Release(buffer) return nil, err } buffer.Slice(0, int(length)) authBytes := buffer.Value[:AuthSize] payload := buffer.Value[AuthSize:] actualAuthBytes := this.auth.Authenticate(nil, payload) if !serial.BytesLiteral(authBytes).Equals(serial.BytesLiteral(actualAuthBytes)) { alloc.Release(buffer) log.Debug("AuthenticationReader: Unexpected auth: ", authBytes) return nil, transport.ErrorCorruptedPacket } buffer.Value = payload return buffer, nil }
// ReaderToChan dumps all content from a given reader to a chan by constantly reading it until EOF. func ReaderToChan(stream chan<- *alloc.Buffer, reader Reader) error { for { buffer, err := reader.Read() if alloc.Len(buffer) > 0 { stream <- buffer } else { alloc.Release(buffer) } if err != nil { return err } } }
func (this *AdaptiveReader) Read() (*alloc.Buffer, error) { buffer, err := ReadFrom(this.reader, this.allocate()) if buffer.IsFull() && !this.isLarge { this.allocate = alloc.NewLargeBuffer this.isLarge = true } else if !buffer.IsFull() { this.allocate = alloc.NewBuffer this.isLarge = false } if err != nil { alloc.Release(buffer) return nil, err } return buffer, nil }