@@ -99,19 +99,19 @@ type includedNode struct {
99
99
// model interface{} should be a pointer to a struct.
100
100
func UnmarshalPayload (in io.Reader , model interface {}) error {
101
101
payload := new (OnePayload )
102
- includedMap := make (map [string ]* includedNode )
102
+ included := make (map [string ]* includedNode )
103
103
104
104
if err := json .NewDecoder (in ).Decode (payload ); err != nil {
105
105
return err
106
106
}
107
107
108
108
if payload .Included != nil {
109
- for _ , included := range payload .Included {
110
- key := fmt .Sprintf ("%s,%s" , included .Type , included .ID )
111
- includedMap [key ] = & includedNode {included , nil }
109
+ for _ , include := range payload .Included {
110
+ key := fmt .Sprintf ("%s,%s" , include .Type , include .ID )
111
+ included [key ] = & includedNode {include , nil }
112
112
}
113
113
114
- return unmarshalNode (payload .Data , reflect .ValueOf (model ), & includedMap )
114
+ return unmarshalNode (payload .Data , reflect .ValueOf (model ), & included )
115
115
}
116
116
return unmarshalNode (payload .Data , reflect .ValueOf (model ), nil )
117
117
}
@@ -125,19 +125,19 @@ func UnmarshalManyPayload(in io.Reader, t reflect.Type) ([]interface{}, error) {
125
125
return nil , err
126
126
}
127
127
128
- models := []interface {}{} // will be populated from the "data"
129
- includedMap := map [string ]* includedNode {} // will be populate from the "included"
128
+ models := []interface {}{} // will be populated from the "data"
129
+ included := map [string ]* includedNode {} // will be populate from the "included"
130
130
131
131
if payload .Included != nil {
132
- for _ , included := range payload .Included {
133
- key := fmt .Sprintf ("%s,%s" , included .Type , included .ID )
134
- includedMap [key ] = & includedNode {included , nil }
132
+ for _ , include := range payload .Included {
133
+ key := fmt .Sprintf ("%s,%s" , include .Type , include .ID )
134
+ included [key ] = & includedNode {include , nil }
135
135
}
136
136
}
137
137
138
138
for _ , data := range payload .Data {
139
139
model := reflect .New (t .Elem ())
140
- err := unmarshalNode (data , model , & includedMap )
140
+ err := unmarshalNode (data , model , & included )
141
141
if err != nil {
142
142
return nil , err
143
143
}
@@ -514,6 +514,8 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*includ
514
514
// model, depending on annotation
515
515
m := reflect .New (fieldValue .Type ().Elem ())
516
516
517
+ // Check if the item in the relationship was already processed elsewhere. Avoids potential infinite recursive loops
518
+ // caused by circular references between included relationships (two included items include one another)
517
519
includedKey := fmt .Sprintf ("%s,%s" , relationship .Data .Type , relationship .Data .ID )
518
520
if included != nil && (* included )[includedKey ] != nil {
519
521
if (* included )[includedKey ].model != nil {
0 commit comments