func (f *fragmentBuffer) push(buf []byte) (bool, error) {
	if f.size()+len(buf) >= fragmentBufferMaxSize {
		return false, errFragmentBufferOverflow
	}

	frag := new(fragment)
	if err := frag.recordLayerHeader.Unmarshal(buf); err != nil {
		return false, err
	}

	// fragment isn't a handshake, we don't need to handle it
	if frag.recordLayerHeader.ContentType != protocol.ContentTypeHandshake {
		return false, nil
	}

	for buf = buf[recordlayer.HeaderSize:]; len(buf) != 0; frag = new(fragment) {
		if err := frag.handshakeHeader.Unmarshal(buf); err != nil {
			return false, err
		}

		if _, ok := f.cache[frag.handshakeHeader.MessageSequence]; !ok {
			f.cache[frag.handshakeHeader.MessageSequence] = []*fragment{}
		}

		// end index should be the length of handshake header but if the handshake
		// was fragmented, we should keep them all
		end := int(handshake.HeaderLength + frag.handshakeHeader.Length)
		if size := len(buf); end > size {
			end = size
		}

		// Discard all headers, when rebuilding the packet we will re-build
		frag.data = append([]byte{}, buf[handshake.HeaderLength:end]...)
		f.cache[frag.handshakeHeader.MessageSequence] = append(f.cache[frag.handshakeHeader.MessageSequence], frag)
		buf = buf[end:]
	}

	return true, nil
}
The program copies an input buffer to an output buffer without verifying that the size of the input buffer is less than the size of the output buffer, leading to a buffer overflow.