Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This [Go (golang)](https://golang.org) library implements parsing and serializat

* Fully implementing the RFC
* Compliant with [the official test suite](https://github.com/httpwg/structured-field-tests)
* Unit tested
* Unit and fuzz tested
* Strongly-typed
* Fast (see [the benchmark](httpwg_test.go))
* No dependencies
Expand Down
7 changes: 4 additions & 3 deletions decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"math"
"strconv"
"strings"
)

const maxDecDigit = 3
Expand All @@ -21,18 +22,18 @@ func marshalDecimal(b io.StringWriter, d float64) error {
const TH = 0.001

rounded := math.RoundToEven(d/TH) * TH
i, frac := math.Modf(math.RoundToEven(d/TH) * TH)
i, frac := math.Modf(rounded)

if i < -999999999999 || i > 999999999999 {
return ErrInvalidDecimal
}

if _, err := b.WriteString(strconv.FormatFloat(rounded, 'f', -1, 64)); err != nil {
if _, err := b.WriteString(strings.TrimRight(strconv.FormatFloat(rounded, 'f', 3, 64), "0")); err != nil {
return err
}

if frac == 0 {
_, err := b.WriteString(".0")
_, err := b.WriteString("0")

return err
}
Expand Down
1 change: 1 addition & 0 deletions decimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func TestDecimalMarshalSFV(t *testing.T) {
{9999999999999, "", false},
{-9999999999999.0, "", false},
{9999999999999.0, "", false},
{1.9, "1.9", true},
}

var b strings.Builder
Expand Down
48 changes: 48 additions & 0 deletions list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,51 @@ func TestUnmarshalList(t *testing.T) {
}
}
}

func FuzzUnmarshalList(f *testing.F) {
testCases := []string{"",
"foo,bar",
"foo, bar",
"foo,\t bar",
"foo", "bar",
`"foo";bar;baz=tok`,
`(foo bar);bat`,
`()`,
` "foo";bar;baz=tok, (foo bar);bat `,
`foo,bar,`,
`foo,baré`,
`é`,
`foo,"bar" é`,
`(foo `,
`(foo);é`,
`("é")`,
`(""`,
`(`,
"1.9",
}

for _, t := range testCases {
f.Add(t)
}

f.Fuzz(func(t *testing.T, b string) {
unmarshaled, err := UnmarshalList([]string{b})
if err != nil {
return
}

reMarshaled, err := Marshal(unmarshaled)
if err != nil {
t.Errorf("Unexpected marshaling error %q for %q, %#v", err, b, unmarshaled)
}

reUnmarshaled, err := UnmarshalList([]string{reMarshaled})
if err != nil {
t.Errorf("Unexpected remarshaling error %q for %q; original %q", err, reMarshaled, b)
}

if !reflect.DeepEqual(unmarshaled, reUnmarshaled) {
t.Errorf("Unmarshaled and re-unmarshaled doesn't match: %#v; %#v", unmarshaled, reUnmarshaled)
}
})
}