]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: panic on recv channel close
authorMauri de Souza Meneguzzo <mauri870@gmail.com>
Thu, 20 Jul 2023 23:14:03 +0000 (23:14 +0000)
committerGopher Robot <gobot@golang.org>
Fri, 21 Jul 2023 05:39:00 +0000 (05:39 +0000)
It is possible to call reflect.ValueOf(ch).Close() on a recv-only channel,
 while close(ch) is a compile-time error. Following the same reflect
semantics as send and recv this should result in a panic.

Fixes #61445

Change-Id: I2a9ee8f45963593a37bd6df4643dd64fb322f9f9
GitHub-Last-Rev: fe2d5e09f5bb5536ac25d1606cf3744fb7a0a4a9
GitHub-Pull-Request: golang/go#61453
Reviewed-on: https://go-review.googlesource.com/c/go/+/511295
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
src/reflect/all_test.go
src/reflect/value.go

index 31f6416ed9ac0aff89d8610c83547fc97e38dfec..afd2d2ef79c3b79275913e667d9f2ba8bad78f6c 100644 (file)
@@ -1706,6 +1706,12 @@ func TestChan(t *testing.T) {
                if i, ok := cv.Recv(); i.Int() != 0 || ok {
                        t.Errorf("after close Recv %d, %t", i.Int(), ok)
                }
+               // Closing a read-only channel
+               shouldPanic("", func() {
+                       c := make(<-chan int, 1)
+                       cv := ValueOf(c)
+                       cv.Close()
+               })
        }
 
        // check creation of unbuffered channel
index 616da6a5c7bcc6ede84d42b250432b97d5ab07ad..127a06e187a22ffa6c2ed3aac82510fd736a8b55 100644 (file)
@@ -1187,10 +1187,16 @@ func (v Value) capNonSlice() int {
 }
 
 // Close closes the channel v.
-// It panics if v's Kind is not Chan.
+// It panics if v's Kind is not Chan or
+// v is a receive-only channel.
 func (v Value) Close() {
        v.mustBe(Chan)
        v.mustBeExported()
+       tt := (*chanType)(unsafe.Pointer(v.typ()))
+       if ChanDir(tt.Dir)&SendDir == 0 {
+               panic("reflect: close of receive-only channel")
+       }
+
        chanclose(v.pointer())
 }