Skip to content

Commit ed6bdf0

Browse files
authored
Merge pull request #82 from BloodHoundAD/BED-4586
chore: make empty data cleanup more aggressive
2 parents 9f36bca + 64c07db commit ed6bdf0

File tree

2 files changed

+43
-10
lines changed

2 files changed

+43
-10
lines changed

models/utils.go

+12
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,23 @@ func StripEmptyEntries(data map[string]any) {
2222
} else if nested, ok := value.(map[string]any); ok { // recursively strip nested maps
2323
StripEmptyEntries(nested)
2424
} else if slice, ok := value.([]any); ok {
25+
value = make([]any, len(value.([]any)))
26+
i := 0
2527
for _, item := range slice {
2628
if mapValue, ok := item.(map[string]any); ok {
2729
StripEmptyEntries(mapValue)
2830
}
31+
if !isEmpty(reflect.ValueOf(item)) {
32+
value.([]any)[i] = item
33+
i++
34+
}
2935
}
36+
value = value.([]any)[:i]
37+
}
38+
39+
// Strip top level if empty post recursive strip
40+
if _, ok := data[key]; ok && isEmpty(reflect.ValueOf(value)) {
41+
delete(data, key)
3042
}
3143
}
3244
}

models/utils_test.go

+31-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package models_test
22

33
import (
44
"encoding/json"
5-
"fmt"
65
"testing"
76

87
"github.com/bloodhoundad/azurehound/v2/models"
@@ -89,7 +88,14 @@ func TestStripEmptyEntries(t *testing.T) {
8988

9089
t.Run("should recursively strip non-empty, nested map[string]any entries", func(t *testing.T) {
9190
data := map[string]any{
92-
"empty": map[string]any{},
91+
"empty": map[string]any{
92+
"false": false,
93+
"emptystring": "",
94+
"emptynest": map[string]any{
95+
"false": false,
96+
"emptystring": "",
97+
},
98+
},
9399
"nonempty": map[string]any{
94100
"emptyprop": 0,
95101
"nonemptyprop": 1,
@@ -106,9 +112,25 @@ func TestStripEmptyEntries(t *testing.T) {
106112
require.Equal(t, 1, nested["nonemptyprop"])
107113
})
108114

109-
t.Run("should strip non-empty slice entries of type map[string]any", func(t *testing.T) {
115+
t.Run("should strip empty slice entries of type map[string]any", func(t *testing.T) {
110116
data := map[string]any{
111-
"empty": []any{},
117+
"empty": []any{
118+
map[string]any{
119+
"false": false,
120+
"emptystring": "",
121+
},
122+
},
123+
"emptynestedslice": []any{
124+
map[string]any{
125+
"nestedslice": []any{
126+
map[string]any{
127+
"false": false,
128+
"emptystring": "",
129+
},
130+
},
131+
"emptystring": "",
132+
},
133+
},
112134
"nonempty": []any{
113135
map[string]any{
114136
"emptyprop": 0,
@@ -117,13 +139,12 @@ func TestStripEmptyEntries(t *testing.T) {
117139
},
118140
}
119141

120-
fmt.Println(data["nonempty"])
121142
models.StripEmptyEntries(data)
122143
require.Nil(t, data["empty"])
144+
require.Nil(t, data["emptynestedslice"])
123145
require.NotNil(t, data["nonempty"])
124146
require.IsType(t, []any{}, data["nonempty"])
125147
slice := data["nonempty"].([]any)
126-
fmt.Println(slice)
127148
require.IsType(t, map[string]any{}, slice[0])
128149
entry := slice[0].(map[string]any)
129150
require.Nil(t, entry["emptyprop"])
@@ -147,7 +168,7 @@ func TestOmitEmpty(t *testing.T) {
147168
require.Equal(t, `{}`, string(filtered))
148169
})
149170

150-
t.Run("should not omit non-empty basic types", func(t *testing.T) {
171+
t.Run("should not omit non-empty basic types except empty structs", func(t *testing.T) {
151172
data := json.RawMessage(`{
152173
"string": "foo",
153174
"number": 1,
@@ -158,17 +179,17 @@ func TestOmitEmpty(t *testing.T) {
158179

159180
filtered, err := models.OmitEmpty(data)
160181
require.Nil(t, err)
161-
require.Equal(t, `{"array":[1],"boolean":true,"number":1,"object":{},"string":"foo"}`, string(filtered))
182+
require.Equal(t, `{"array":[1],"boolean":true,"number":1,"string":"foo"}`, string(filtered))
162183
})
163184

164-
t.Run("should not omit empty struct/object types, just their empty properties", func(t *testing.T) {
185+
t.Run("should omit empty struct/object types, just their empty properties", func(t *testing.T) {
165186
data := json.RawMessage(`{
166187
"object": { "bar": "" }
167188
}`)
168189

169190
filtered, err := models.OmitEmpty(data)
170191
require.Nil(t, err)
171-
require.Equal(t, `{"object":{}}`, string(filtered))
192+
require.Equal(t, `{}`, string(filtered))
172193
})
173194

174195
t.Run("should recursively strip non-empty, nested object entries", func(t *testing.T) {

0 commit comments

Comments
 (0)