Skip to content

Commit 2c603f5

Browse files
authored
backend: fix unmarshaling empty refids (#1189)
1 parent 7a22b2a commit 2c603f5

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

backend/json.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,24 @@ func readQueryDataResultsJSON(qdr *QueryDataResponse, iter *jsoniter.Iterator) {
149149

150150
qdr.Responses = make(Responses)
151151

152-
for l2Field := iter.ReadObject(); l2Field != ""; l2Field = iter.ReadObject() {
152+
l2Field := iter.ReadObject()
153+
for {
154+
// the response may have an empty-string refId. this is not allowed,
155+
// but it may happen, and we want to be able to handle the case.
156+
// jsonIter uses empty-string to signalize both of these cases:
157+
// - end of object
158+
// - key found with the value empty-string
159+
// to be able to differentiate between these two cases, we use the `WhatIsNext()`
160+
// function, that tells us what is coming next, but does not consume content.
161+
if (l2Field == "") && (iter.WhatIsNext() != jsoniter.ObjectValue) {
162+
break
163+
}
164+
153165
dr := DataResponse{}
154166
readDataResponseJSON(&dr, iter)
155167
qdr.Responses[l2Field] = dr
168+
169+
l2Field = iter.ReadObject()
156170
}
157171

158172
default:

backend/json_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,39 @@ func TestQueryDataResponseOrdering(t *testing.T) {
143143

144144
require.JSONEq(t, expected, string(b))
145145
}
146+
147+
func testQueryDataResponseRoundtrip(t *testing.T, qdr *backend.QueryDataResponse) {
148+
t.Helper()
149+
// to json
150+
b, err := json.Marshal(qdr)
151+
require.NoError(t, err)
152+
153+
// from json
154+
qdr2 := &backend.QueryDataResponse{}
155+
err = json.Unmarshal(b, qdr2)
156+
require.NoError(t, err)
157+
158+
// to json again, to compare
159+
b2, err := json.Marshal(qdr2)
160+
require.NoError(t, err)
161+
require.Equal(t, b2, b)
162+
}
163+
164+
func TestQueryDataWithoutRefID(t *testing.T) {
165+
qdr := backend.NewQueryDataResponse()
166+
qdr.Responses[""] = testDataResponse()
167+
168+
testQueryDataResponseRoundtrip(t, qdr)
169+
}
170+
171+
func TestQueryDataWithtRefID(t *testing.T) {
172+
qdr := backend.NewQueryDataResponse()
173+
qdr.Responses["A"] = testDataResponse()
174+
175+
testQueryDataResponseRoundtrip(t, qdr)
176+
}
177+
178+
func TestQueryDataWithoutResponses(t *testing.T) {
179+
qdr := backend.NewQueryDataResponse()
180+
testQueryDataResponseRoundtrip(t, qdr)
181+
}

0 commit comments

Comments
 (0)