Repository: grpc/grpc-go
File: credentials/alts/internal/conn/record.go (Go)

Code before:
	if !p.isClosed {
		p.isClosed = true
		mem.DefaultBufferPool().Put(p.protectedPointer)
		mem.DefaultBufferPool().Put(p.bufPointer)
	}
	return p.Conn.Close()
}

// Read reads and decrypts a frame from the underlying connection, and copies the
// decrypted payload into b. If the size of the payload is greater than len(b),
// Read retains the remaining bytes in an internal buffer, and subsequent calls
// to Read will read from this buffer until it is exhausted.
func (p *conn) Read(b []byte) (n int, err error) {
	if p.isClosed {
		return 0, io.EOF
	}
	if len(p.buf) == 0 {
		var framedMsg []byte
		framedMsg, p.nextFrame, err = ParseFramedMsg(p.nextFrame, altsRecordLengthLimit)
		if err != nil {
			return n, err
		}
		// Check whether the next frame to be decrypted has been
		// completely received yet.
		if len(framedMsg) == 0 {
			p.protected = p.protected[:copy(p.protected, p.nextFrame)]
			// Always copy next incomplete frame to the beginning of
			// the protected buffer and reset nextFrame to it.
			p.nextFrame = p.protected
		}
		// Check whether a complete frame has been received yet.
		for len(framedMsg) == 0 {
			if len(p.protected) == cap(p.protected) {
				// We can parse the length header to know exactly how large
				// the buffer needs to be to hold the entire frame.
				length, didParse := ParseMessageLength(p.protected)
				if !didParse {
					// The protected buffer is initialized with a capacity of
					// larger than 4B. It should always hold the message length
					// header.
					panic(fmt.Sprintf("protected buffer length shorter than expected: %d vs %d", len(p.protected), MsgLenFieldSize))
				}
				tmp := mem.DefaultBufferPool().Get(int(length))
				copy(*tmp, p.protected)
				p.protected = (*tmp)[:len(p.protected)]
				mem.DefaultBufferPool().Put(p.protectedPointer)
				p.protectedPointer = tmp
			}
			n, err = p.Conn.Read(p.protected[len(p.protected):cap(p.protected)])
			if err != nil {
				return 0, err

Review comment (bug):
I think this line is a little challenging to reason about since it's modifying `p.protectd` in several ways. Can it be broken up without performance hits, or will not immediately slicing to the right length cause an issue?

Code after:
		// completely received yet.
		if len(framedMsg) == 0 {
			copy(p.protected, p.nextFrame)
			p.protected = p.protected[:len(p.nextFrame)]
			// Always copy next incomplete frame to the beginning of
			// the protected buffer and reset nextFrame to it.
			p.nextFrame = p.protected
		}
		// Check whether a complete frame has been received yet.
		for len(framedMsg) == 0 {
			if len(p.protected) == cap(p.protected) {
				// We can parse the length header to know exactly how large
				// the buffer needs to be to hold the entire frame.
				length, didParse := parseMessageLength(p.protected)
				if !didParse {
					// The protected buffer is initialized with a capacity of
					// larger than 4B. It should always hold the message length
					// header.
					panic(fmt.Sprintf("protected buffer length shorter than expected: %d vs %d", len(p.protected), MsgLenFieldSize))
				}
				oldProtectedBuf := p.protected
				p.protected = make([]byte, int(length)+MsgLenFieldSize)
				copy(p.protected, oldProtectedBuf)
				p.protected = p.protected[:len(oldProtectedBuf)]
			}
			n, err = p.Conn.Read(p.protected[len(p.protected):cap(p.protected)])
			if err != nil {
				return 0, err
			}
			p.protected = p.protected[:len(p.protected)+n]
			framedMsg, p.nextFrame, err = ParseFramedMsg(p.protected, altsRecordLengthLimit)
			if err != nil {
				return 0, err
			}
		}
		// Now we have a complete frame, decrypted it.
		msg := framedMsg[MsgLenFieldSize:]
		msgType := binary.LittleEndian.Uint32(msg[:msgTypeFieldSize])
		if msgType&0xff != altsRecordMsgType {
			return 0, fmt.Errorf("received frame with incorrect message type %v, expected lower byte %v",
				msgType, altsRecordMsgType)
		}
		ciphertext := msg[msgTypeFieldSize:]

		// Decrypt directly into the buffer, avoiding a copy from p.buf if
		// possible.
		if len(b) >= len(ciphertext) {
			dec, err := p.crypto.Decrypt(b[:0], ciphertext)
			if err != nil {
				return 0, err
			}