<commit_before>package handshake

import (
	"github.com/lucas-clemente/quic-go/internal/protocol"
	"github.com/marten-seemann/qtls"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("TLS Extension Handler, for the server", func() {
	var (
		handlerServer tlsExtensionHandler
		handlerClient tlsExtensionHandler
	)

	BeforeEach(func() {
		handlerServer = newExtensionHandler(
			[]byte("foobar"),
			protocol.PerspectiveServer,
		)
		handlerClient = newExtensionHandler(
			[]byte("raboof"),
			protocol.PerspectiveClient,
		)
	})

	Context("for the server", func() {
		Context("sending", func() {
			It("only adds TransportParameters for the Encrypted Extensions", func() {
				// test 2 other handshake types
				Expect(handlerServer.GetExtensions(uint8(typeCertificate))).To(BeEmpty())
				Expect(handlerServer.GetExtensions(uint8(typeFinished))).To(BeEmpty())
			})

			It("adds TransportParameters to the EncryptedExtensions message", func() {
				exts := handlerServer.GetExtensions(uint8(typeEncryptedExtensions))
				Expect(exts).To(HaveLen(1))
				Expect(exts[0].Type).To(BeEquivalentTo(quicTLSExtensionType))
				Expect(exts[0].Data).To(Equal([]byte("foobar")))
			})
		})

		Context("receiving", func() {
			var chExts []qtls.Extension

			BeforeEach(func() {
				chExts = handlerClient.GetExtensions(uint8(typeClientHello))
				Expect(chExts).To(HaveLen(1))
			})

			It("sends the extension on the channel", func() {
				go func() {
					defer GinkgoRecover()
					handlerServer.ReceivedExtensions(uint8(typeClientHello), chExts)
				}()

				var data []byte
				Eventually(handlerServer.TransportParameters()).Should(Receive(&data))
				Expect(data).To(Equal([]byte("raboof")))
			})

			It("sends nil on the channel if the extension is missing", func() {
				go func() {
					defer GinkgoRecover()
					handlerServer.ReceivedExtensions(uint8(typeClientHello), nil)
				}()

				var data []byte
				Eventually(handlerServer.TransportParameters()).Should(Receive(&data))
				Expect(data).To(BeEmpty())
			})

			It("ignores extensions with different code points", func() {
				go func() {
					defer GinkgoRecover()
					exts := []qtls.Extension{{Type: 0x1337, Data: []byte("invalid")}}
					handlerServer.ReceivedExtensions(uint8(typeClientHello), exts)
				}()

				var data []byte
				Eventually(handlerServer.TransportParameters()).Should(Receive())
				Expect(data).To(BeEmpty())
			})

			It("ignores extensions that are not sent with the ClientHello", func() {
				go func() {
					defer GinkgoRecover()
					handlerServer.ReceivedExtensions(uint8(typeFinished), chExts)
				}()

				Consistently(handlerServer.TransportParameters()).ShouldNot(Receive())
			})
		})
	})

	Context("for the client", func() {
		Context("sending", func() {
			It("only adds TransportParameters for the Encrypted Extensions", func() {
				// test 2 other handshake types
				Expect(handlerClient.GetExtensions(uint8(typeCertificate))).To(BeEmpty())
				Expect(handlerClient.GetExtensions(uint8(typeFinished))).To(BeEmpty())
			})

			It("adds TransportParameters to the ClientHello message", func() {
				exts := handlerClient.GetExtensions(uint8(typeClientHello))
				Expect(exts).To(HaveLen(1))
				Expect(exts[0].Type).To(BeEquivalentTo(quicTLSExtensionType))
				Expect(exts[0].Data).To(Equal([]byte("raboof")))
			})
		})

		Context("receiving", func() {
			var chExts []qtls.Extension

			BeforeEach(func() {
				chExts = handlerServer.GetExtensions(uint8(typeEncryptedExtensions))
				Expect(chExts).To(HaveLen(1))
			})

			It("sends the extension on the channel", func() {
				go func() {
					defer GinkgoRecover()
					handlerClient.ReceivedExtensions(uint8(typeEncryptedExtensions), chExts)
				}()

				var data []byte
				Eventually(handlerClient.TransportParameters()).Should(Receive(&data))
				Expect(data).To(Equal([]byte("foobar")))
			})

			It("sends nil on the channel if the extension is missing", func() {
				go func() {
					defer GinkgoRecover()
					handlerClient.ReceivedExtensions(uint8(typeEncryptedExtensions), nil)
				}()

				var data []byte
				Eventually(handlerClient.TransportParameters()).Should(Receive(&data))
				Expect(data).To(BeEmpty())
			})

			It("ignores extensions with different code points", func() {
				go func() {
					defer GinkgoRecover()
					exts := []qtls.Extension{{Type: 0x1337, Data: []byte("invalid")}}
					handlerClient.ReceivedExtensions(uint8(typeEncryptedExtensions), exts)
				}()

				var data []byte
				Eventually(handlerClient.TransportParameters()).Should(Receive())
				Expect(data).To(BeEmpty())
			})

			It("ignores extensions that are not sent with the EncryptedExtensions", func() {
				go func() {
					defer GinkgoRecover()
					handlerClient.ReceivedExtensions(uint8(typeFinished), chExts)
				}()

				Consistently(handlerClient.TransportParameters()).ShouldNot(Receive())
			})
		})
	})
})<commit_msg>fix race condition in the TLS extension handler test<commit_after>package handshake

import (
	"github.com/lucas-clemente/quic-go/internal/protocol"
	"github.com/marten-seemann/qtls"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("TLS Extension Handler, for the server", func() {
	var (
		handlerServer tlsExtensionHandler
		handlerClient tlsExtensionHandler
	)

	BeforeEach(func() {
		handlerServer = newExtensionHandler(
			[]byte("foobar"),
			protocol.PerspectiveServer,
		)
		handlerClient = newExtensionHandler(
			[]byte("raboof"),
			protocol.PerspectiveClient,
		)
	})

	Context("for the server", func() {
		Context("sending", func() {
			It("only adds TransportParameters for the Encrypted Extensions", func() {
				// test 2 other handshake types
				Expect(handlerServer.GetExtensions(uint8(typeCertificate))).To(BeEmpty())
				Expect(handlerServer.GetExtensions(uint8(typeFinished))).To(BeEmpty())
			})

			It("adds TransportParameters to the EncryptedExtensions message", func() {
				exts := handlerServer.GetExtensions(uint8(typeEncryptedExtensions))
				Expect(exts).To(HaveLen(1))
				Expect(exts[0].Type).To(BeEquivalentTo(quicTLSExtensionType))
				Expect(exts[0].Data).To(Equal([]byte("foobar")))
			})
		})

		Context("receiving", func() {
			var chExts []qtls.Extension

			BeforeEach(func() {
				chExts = handlerClient.GetExtensions(uint8(typeClientHello))
				Expect(chExts).To(HaveLen(1))
			})

			It("sends the extension on the channel", func() {
				go func() {
					defer GinkgoRecover()
					handlerServer.ReceivedExtensions(uint8(typeClientHello), chExts)
				}()

				var data []byte
				Eventually(handlerServer.TransportParameters()).Should(Receive(&data))
				Expect(data).To(Equal([]byte("raboof")))
			})

			It("sends nil on the channel if the extension is missing", func() {
				go func() {
					defer GinkgoRecover()
					handlerServer.ReceivedExtensions(uint8(typeClientHello), nil)
				}()

				var data []byte
				Eventually(handlerServer.TransportParameters()).Should(Receive(&data))
				Expect(data).To(BeEmpty())
			})

			It("ignores extensions with different code points", func() {
				go func() {
					defer GinkgoRecover()
					exts := []qtls.Extension{{Type: 0x1337, Data: []byte("invalid")}}
					handlerServer.ReceivedExtensions(uint8(typeClientHello), exts)
				}()

				var data []byte
				Eventually(handlerServer.TransportParameters()).Should(Receive())
				Expect(data).To(BeEmpty())
			})

			It("ignores extensions that are not sent with the ClientHello", func() {
				done := make(chan struct{})
				go func() {
					defer GinkgoRecover()
					handlerServer.ReceivedExtensions(uint8(typeFinished), chExts)
					close(done)
				}()

				Consistently(handlerServer.TransportParameters()).ShouldNot(Receive())
				Eventually(done).Should(BeClosed())
			})
		})
	})

	Context("for the client", func() {
		Context("sending", func() {
			It("only adds TransportParameters for the Encrypted Extensions", func() {
				// test 2 other handshake types
				Expect(handlerClient.GetExtensions(uint8(typeCertificate))).To(BeEmpty())
				Expect(handlerClient.GetExtensions(uint8(typeFinished))).To(BeEmpty())
			})

			It("adds TransportParameters to the ClientHello message", func() {
				exts := handlerClient.GetExtensions(uint8(typeClientHello))
				Expect(exts).To(HaveLen(1))
				Expect(exts[0].Type).To(BeEquivalentTo(quicTLSExtensionType))
				Expect(exts[0].Data).To(Equal([]byte("raboof")))
			})
		})

		Context("receiving", func() {
			var chExts []qtls.Extension

			BeforeEach(func() {
				chExts = handlerServer.GetExtensions(uint8(typeEncryptedExtensions))
				Expect(chExts).To(HaveLen(1))
			})

			It("sends the extension on the channel", func() {
				go func() {
					defer GinkgoRecover()
					handlerClient.ReceivedExtensions(uint8(typeEncryptedExtensions), chExts)
				}()

				var data []byte
				Eventually(handlerClient.TransportParameters()).Should(Receive(&data))
				Expect(data).To(Equal([]byte("foobar")))
			})

			It("sends nil on the channel if the extension is missing", func() {
				go func() {
					defer GinkgoRecover()
					handlerClient.ReceivedExtensions(uint8(typeEncryptedExtensions), nil)
				}()

				var data []byte
				Eventually(handlerClient.TransportParameters()).Should(Receive(&data))
				Expect(data).To(BeEmpty())
			})

			It("ignores extensions with different code points", func() {
				go func() {
					defer GinkgoRecover()
					exts := []qtls.Extension{{Type: 0x1337, Data: []byte("invalid")}}
					handlerClient.ReceivedExtensions(uint8(typeEncryptedExtensions), exts)
				}()

				var data []byte
				Eventually(handlerClient.TransportParameters()).Should(Receive())
				Expect(data).To(BeEmpty())
			})

			It("ignores extensions that are not sent with the EncryptedExtensions", func() {
				done := make(chan struct{})
				go func() {
					defer GinkgoRecover()
					handlerClient.ReceivedExtensions(uint8(typeFinished), chExts)
					close(done)
				}()

				Consistently(handlerClient.TransportParameters()).ShouldNot(Receive())
				Eventually(done).Should(BeClosed())
			})
		})
	})
})
{'fraction_non_alphanumeric': 0.14457831325301204, 'fraction_numerical': 0.007169172558000598, 'mean_word_length': 4.36825227151256, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6195064', 'n_tokens_mistral': 3816, 'n_tokens_neox': 3034, 'n_words': 564}