@@ -99,19 +99,19 @@ type includedNode struct {
9999// model interface{} should be a pointer to a struct.
100100func UnmarshalPayload (in io.Reader , model interface {}) error {
101101 payload := new (OnePayload )
102- includedMap := make (map [string ]* includedNode )
102+ included := make (map [string ]* includedNode )
103103
104104 if err := json .NewDecoder (in ).Decode (payload ); err != nil {
105105 return err
106106 }
107107
108108 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 }
112112 }
113113
114- return unmarshalNode (payload .Data , reflect .ValueOf (model ), & includedMap )
114+ return unmarshalNode (payload .Data , reflect .ValueOf (model ), & included )
115115 }
116116 return unmarshalNode (payload .Data , reflect .ValueOf (model ), nil )
117117}
@@ -125,19 +125,19 @@ func UnmarshalManyPayload(in io.Reader, t reflect.Type) ([]interface{}, error) {
125125 return nil , err
126126 }
127127
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"
130130
131131 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 }
135135 }
136136 }
137137
138138 for _ , data := range payload .Data {
139139 model := reflect .New (t .Elem ())
140- err := unmarshalNode (data , model , & includedMap )
140+ err := unmarshalNode (data , model , & included )
141141 if err != nil {
142142 return nil , err
143143 }
@@ -514,6 +514,8 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*includ
514514 // model, depending on annotation
515515 m := reflect .New (fieldValue .Type ().Elem ())
516516
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)
517519 includedKey := fmt .Sprintf ("%s,%s" , relationship .Data .Type , relationship .Data .ID )
518520 if included != nil && (* included )[includedKey ] != nil {
519521 if (* included )[includedKey ].model != nil {
0 commit comments