From 7beae1691f2638f171f9c836af2c244cadef0893 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Sat, 20 Oct 2018 17:00:25 +1030 Subject: [PATCH] fix false positive detection of cycles with slice in first field of struct --- dump.go | 5 +++++ dump_test.go | 30 ++++++++++++++++++++++-------- spew_test.go | 4 ++-- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/dump.go b/dump.go index 1099f1d..3f819c5 100644 --- a/dump.go +++ b/dump.go @@ -412,6 +412,10 @@ func (d *dumpState) dump(v reflect.Value, wasPtr, static bool, addr uintptr) { d.w.Write(closeParenBytes) break } + if v.Len() == 0 { + d.dumpSlice(v) + break + } // Remove pointers at or below the current depth from map used to detect // circular refs. for k, depth := range d.pointers { @@ -419,6 +423,7 @@ func (d *dumpState) dump(v reflect.Value, wasPtr, static bool, addr uintptr) { delete(d.pointers, k) } } + addr = v.Index(0).Addr().Pointer() if pd, ok := d.pointers[addr]; ok && pd < d.depth { d.w.Write(circularBytes) break diff --git a/dump_test.go b/dump_test.go index e8d9fa0..5a37b6a 100644 --- a/dump_test.go +++ b/dump_test.go @@ -887,9 +887,7 @@ var sliceElementCycles = []struct { // the cycle as the initial v seen by utter.Dump was not // addressable. want: `[]interface{}{ - []interface{}{ - []interface{}(), - }, + []interface{}(), } `, }, @@ -900,9 +898,7 @@ var sliceElementCycles = []struct { return &r }(), want: `&[]interface{}{ - []interface{}{ - []interface{}(), - }, + []interface{}(), } `, }, @@ -913,7 +909,7 @@ var sliceElementCycles = []struct { return &r }(), want: `&[]interface{}{ - (*[]interface{})(), + &[]interface{}(), } `, }, @@ -948,7 +944,25 @@ var sliceElementCycles = []struct { return &r }(), want: `&utter_test.recurrence{ - v: []interface{}(), + v: []interface{}{ + utter_test.recurrence{ + v: []interface{}(), + }, + }, +} +`, + }, + { + v: func() interface{} { + type container struct { + v []int + } + return &container{[]int{1}} + }(), + want: `&utter_test.container{ + v: []int{ + int(1), + }, } `, }, diff --git a/spew_test.go b/spew_test.go index 720bfd7..71f2cdd 100644 --- a/spew_test.go +++ b/spew_test.go @@ -182,7 +182,7 @@ func initSpewTests() { {comPtrDefault, fCSFdump, spp, fmt.Sprintf("&&struct { *int } /*%p->%p*/ {\n int: &int /*%p*/ (10),\n}\n", spp, sp, v)}, {comPtrDefault, fCSFdump, c, fmt.Sprintf("[]interface{}{\n"+ " int( /*%p*/ 5),\n int( /*%p*/ 5),\n"+ - " &int /*%[1]p*/ (5),\n &int /*%p*/ (5),\n}\n", &c[0], &c[1])}, + " (*interface{}) /*%[1]p*/ (),\n &int /*%p*/ (5),\n}\n", &c[0], &c[1])}, {comPtrDefault, fCSFdump, d, fmt.Sprintf("&struct { a [2]int; p *int } /*%p*/ {\n"+ " a: [2]int{\n int(0),\n"+ " int( /*%p*/ 10),\n },\n"+ @@ -193,7 +193,7 @@ func initSpewTests() { " int(1): []interface{}{\n"+ " int( /*%p*/ 5),\n"+ " int( /*%p*/ 5),\n"+ - " &int /*%[1]p*/ (5),\n"+ + " (*interface{}) /*%[1]p*/ (),\n"+ " &int /*%p*/ (5),\n },\n}\n", &c[0], &c[1])}, {bs8Default, fCSFdump, []byte{1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3}, "[]uint8{\n" + " 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x01, 0x02, // |........|\n" +