Skip to content

Commit 9fd0003

Browse files
authored
Merge pull request #610 from iamemilio/encode_bug
Defend against encoding bug until we solve it
2 parents d824822 + 09541bf commit 9fd0003

File tree

3 files changed

+90
-9
lines changed

3 files changed

+90
-9
lines changed

v3/internal/jsonx/encode_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package jsonx
55

66
import (
77
"bytes"
8+
"fmt"
89
"math"
910
"testing"
1011
)
@@ -28,6 +29,30 @@ func TestAppendFloat(t *testing.T) {
2829
}
2930
}
3031

32+
func TestAppendFloat32(t *testing.T) {
33+
buf := &bytes.Buffer{}
34+
35+
err := AppendFloat32(buf, float32(math.NaN()))
36+
if err == nil {
37+
t.Error("AppendFloat(NaN) should return an error")
38+
}
39+
40+
err = AppendFloat32(buf, float32(math.Inf(1)))
41+
if err == nil {
42+
t.Error("AppendFloat(+Inf) should return an error")
43+
}
44+
45+
err = AppendFloat32(buf, float32(math.Inf(-1)))
46+
if err == nil {
47+
t.Error("AppendFloat(-Inf) should return an error")
48+
}
49+
50+
err = AppendFloat32(buf, float32(12.5))
51+
if err != nil {
52+
t.Error("AppendFloat(12.5) should not return an error")
53+
}
54+
}
55+
3156
func TestAppendFloats(t *testing.T) {
3257
buf := &bytes.Buffer{}
3358

@@ -166,6 +191,15 @@ var encodeStringTests = []struct {
166191
{"\\", `"\\"`},
167192
{`"`, `"\""`},
168193
{"the\u2028quick\t\nbrown\u2029fox", `"the\u2028quick\t\nbrown\u2029fox"`},
194+
195+
//extra edge cases
196+
{string([]byte{237, 159, 193}), `"\ufffd\ufffd\ufffd"`}, // invalid utf8
197+
{string([]byte{55, 237, 159, 193, 55}), `"7\ufffd\ufffd\ufffd7"`}, // invalid utf8 surrounded by valid utf8
198+
{`abcdefghijklmnopqrstuvwxyz1234567890`, `"abcdefghijklmnopqrstuvwxyz1234567890"`}, // alphanumeric
199+
{"'", `"'"`},
200+
{``, `""`},
201+
{`\`, `"\\"`},
202+
{fmt.Sprintf("%c", rune(65533)), fmt.Sprintf("\"%c\"", rune(65533))}, // invalid rune utf8 symbol (valid utf8)
169203
}
170204

171205
func TestAppendString(t *testing.T) {
@@ -181,6 +215,41 @@ func TestAppendString(t *testing.T) {
181215
}
182216
}
183217

218+
func TestAppendStringArray(t *testing.T) {
219+
buf := &bytes.Buffer{}
220+
221+
var encodeStringArrayTests = []struct {
222+
in []string
223+
out string
224+
}{
225+
{
226+
in: []string{
227+
"hi",
228+
"foo",
229+
},
230+
out: `["hi","foo"]`,
231+
},
232+
{
233+
in: []string{
234+
"foo",
235+
},
236+
out: `["foo"]`,
237+
},
238+
{
239+
in: []string{},
240+
out: `[]`,
241+
},
242+
}
243+
244+
for _, tt := range encodeStringArrayTests {
245+
buf.Reset()
246+
247+
AppendStringArray(buf, tt.in...)
248+
if got := buf.String(); got != tt.out {
249+
t.Errorf("AppendString(%q) = %#q, want %#q", tt.in, got, tt.out)
250+
}
251+
}
252+
}
184253
func BenchmarkAppendString(b *testing.B) {
185254
buf := &bytes.Buffer{}
186255

v3/newrelic/attributes_from_internal.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,8 @@ func (attr agentAttributes) Add(id string, stringVal string, otherVal interface{
275275
}
276276
}
277277

278-
//
279278
// Remove is used to remove agent attributes.
280279
// It is not an error if the attribute wasn't present to begin with.
281-
//
282280
func (attr agentAttributes) Remove(id string) {
283281
if _, ok := attr[id]; ok {
284282
delete(attr, id)
@@ -453,14 +451,14 @@ func writeAttributeValueJSON(w *jsonFieldsWriter, key string, val interface{}) {
453451
}
454452

455453
func agentAttributesJSON(a *attributes, buf *bytes.Buffer, d destinationSet) {
456-
if nil == a {
454+
if a == nil {
457455
buf.WriteString("{}")
458456
return
459457
}
460458
w := jsonFieldsWriter{buf: buf}
461459
buf.WriteByte('{')
462460
for id, val := range a.Agent {
463-
if 0 != a.config.agentDests[id]&d {
461+
if a.config.agentDests[id]&d != 0 {
464462
if val.stringVal != "" {
465463
w.stringField(id, val.stringVal)
466464
} else {
@@ -478,12 +476,12 @@ func userAttributesJSON(a *attributes, buf *bytes.Buffer, d destinationSet, extr
478476
w := jsonFieldsWriter{buf: buf}
479477
for key, val := range extraAttributes {
480478
outputDest := applyAttributeConfig(a.config, key, d)
481-
if 0 != outputDest&d {
479+
if outputDest&d != 0 {
482480
writeAttributeValueJSON(&w, key, val)
483481
}
484482
}
485483
for name, atr := range a.user {
486-
if 0 != atr.dests&d {
484+
if atr.dests&d != 0 {
487485
if _, found := extraAttributes[name]; found {
488486
continue
489487
}

v3/newrelic/internal_app.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,30 @@ func (app *app) doHarvest(h *harvest, harvestStart time.Time, run *appRun) {
7171
payloads := h.Payloads(app.config.DistributedTracer.Enabled)
7272
for _, p := range payloads {
7373
cmd := p.EndpointMethod()
74+
var data []byte
75+
76+
defer func() {
77+
if r := recover(); r != nil {
78+
app.Warn("panic occured when creating harvest data", map[string]interface{}{
79+
"cmd": cmd,
80+
"panic": r,
81+
})
82+
83+
// make sure the loop continues
84+
data = nil
85+
}
86+
}()
87+
7488
data, err := p.Data(run.Reply.RunID.String(), harvestStart)
7589

76-
if nil != err {
90+
if err != nil {
7791
app.Warn("unable to create harvest data", map[string]interface{}{
7892
"cmd": cmd,
7993
"error": err.Error(),
8094
})
8195
continue
8296
}
83-
if nil == data {
97+
if data == nil {
8498
continue
8599
}
86100

@@ -103,7 +117,7 @@ func (app *app) doHarvest(h *harvest, harvestStart time.Time, run *appRun) {
103117
return
104118
}
105119

106-
if nil != resp.Err {
120+
if resp.Err != nil {
107121
app.Warn("harvest failure", map[string]interface{}{
108122
"cmd": cmd,
109123
"error": resp.Err.Error(),

0 commit comments

Comments
 (0)