Compare commits

..

8 Commits

Author SHA1 Message Date
Thomas Pelletier 643c251c4b Fix panic when unmarshaling into a map twice (#854)
Fixes #851
2023-02-28 17:34:24 +01:00
Thomas Pelletier 8a416daa69 Fix error report of type mismatch on inline tables (#853)
Parser did not track the location of the faulty inline table in the
document, and unmarshaler tried to the use the non-raw data field of the
AST node, both resulting into a panic when generating the parser error.

Fixes #850
2023-02-28 17:06:49 +01:00
Andreas Deininger fcd9179b7d Fixes typos (#849) 2023-02-13 03:57:48 -08:00
Marty 9f5726004e Allow integers to be unmarshaled into floats (#841)
Co-authored-by: Marty <martin@windscribe.com>
2023-02-09 12:02:25 -05:00
Thomas Pelletier c4a2eef8a4 Fix go 1.20 version in github actions (#848)
YAML interprets 1.20 as 1.2 without explicitely being a string.
2023-02-09 12:00:14 -05:00
Thomas Pelletier b58c20aa49 Upgrade go 1.20 (#847)
Fixes #842
2023-02-08 18:59:58 -05:00
Cuong Manh Le 090cccf4ba Fix inline table first key value whitespace (#837)
Co-authored-by: Cuong Manh Le <cuong@windscribe.com>
2023-02-01 12:00:09 +01:00
DavidKorczynski 58a592bbf8 ci: add CIFuzz integration (#831)
Signed-off-by: David Korczynski <david@adalogics.com>
2022-11-21 18:51:48 -05:00
15 changed files with 99 additions and 28 deletions
+26
View File
@@ -0,0 +1,26 @@
name: CIFuzz
on: [pull_request]
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'go-toml'
dry-run: false
language: go
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'go-toml'
fuzz-seconds: 300
dry-run: false
language: go
- name: Upload Crash
uses: actions/upload-artifact@v3
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts
+1 -1
View File
@@ -15,6 +15,6 @@ jobs:
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: 1.19
go-version: "1.20"
- name: Run tests with coverage
run: ./ci.sh coverage -d "${GITHUB_BASE_REF-HEAD}"
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19
go-version: "1.20"
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
os: [ 'ubuntu-latest', 'windows-latest', 'macos-latest']
go: [ '1.18', '1.19' ]
go: [ '1.19', '1.20' ]
runs-on: ${{ matrix.os }}
name: ${{ matrix.go }}/${{ matrix.os }}
steps:
+1 -1
View File
@@ -553,7 +553,7 @@ complete solutions exist out there.
## Versioning
Go-toml follows [Semantic Versioning](http://semver.org/). The supported version
Go-toml follows [Semantic Versioning](https://semver.org). The supported version
of [TOML](https://github.com/toml-lang/toml) is indicated at the beginning of
this document. The last two major versions of Go are supported
(see [Go Release Policy](https://golang.org/doc/devel/release.html#policy)).
+8 -1
View File
@@ -7,13 +7,20 @@ import (
"github.com/stretchr/testify/require"
)
func TestFastSimple(t *testing.T) {
func TestFastSimpleInt(t *testing.T) {
m := map[string]int64{}
err := toml.Unmarshal([]byte(`a = 42`), &m)
require.NoError(t, err)
require.Equal(t, map[string]int64{"a": 42}, m)
}
func TestFastSimpleFloat(t *testing.T) {
m := map[string]float64{}
err := toml.Unmarshal([]byte("a = 42\nb = 1.1\nc = 12341234123412341234123412341234"), &m)
require.NoError(t, err)
require.Equal(t, map[string]float64{"a": 42, "b": 1.1, "c": 1.2341234123412342e+31}, m)
}
func TestFastSimpleString(t *testing.T) {
m := map[string]string{}
err := toml.Unmarshal([]byte(`a = "hello"`), &m)
+2 -2
View File
@@ -1,5 +1,5 @@
//go:build go1.18 || go1.19
// +build go1.18 go1.19
//go:build go1.18 || go1.19 || go1.20
// +build go1.18 go1.19 go1.20
package toml_test
+1 -1
View File
@@ -18,7 +18,7 @@ type Program struct {
Usage string
Fn ConvertFn
// Inplace allows the command to take more than one file as argument and
// perform convertion in place on each provided file.
// perform conversion in place on each provided file.
Inplace bool
}
@@ -1085,10 +1085,6 @@ func TestUnmarshalCheckConversionFloatInt(t *testing.T) {
desc: "int",
input: `I = 1e300`,
},
{
desc: "float",
input: `F = 9223372036854775806`,
},
}
for _, test := range testCases {
+1 -1
View File
@@ -357,9 +357,9 @@ func (enc *Encoder) encodeKv(b []byte, ctx encoderCtx, options valueOptions, v r
if !ctx.inline {
b = enc.encodeComment(ctx.indent, options.comment, b)
b = enc.indent(ctx.indent, b)
}
b = enc.indent(ctx.indent, b)
b = enc.encodeKey(b, ctx.key)
b = append(b, " = "...)
+21
View File
@@ -1190,6 +1190,27 @@ func TestMarshalUint64Overflow(t *testing.T) {
require.Error(t, err)
}
func TestIndentWithInlineTable(t *testing.T) {
x := map[string][]map[string]string{
"one": []map[string]string{
{"0": "0"},
{"1": "1"},
},
}
expected := `one = [
{0 = '0'},
{1 = '1'}
]
`
var buf bytes.Buffer
enc := toml.NewEncoder(&buf)
enc.SetIndentTables(true)
enc.SetTablesInline(true)
enc.SetArraysMultiline(true)
require.NoError(t, enc.Encode(x))
assert.Equal(t, expected, buf.String())
}
func ExampleMarshal() {
type MyConfig struct {
Version int
+9 -10
View File
@@ -60,7 +60,7 @@ func (d *Decoder) DisallowUnknownFields() *Decoder {
// are ignored. See Decoder.DisallowUnknownFields() to change this behavior.
//
// When a TOML local date, time, or date-time is decoded into a time.Time, its
// value is represented in time.Local timezone. Otherwise the approriate Local*
// value is represented in time.Local timezone. Otherwise the appropriate Local*
// structure is used. For time values, precision up to the nanosecond is
// supported by truncating extra digits.
//
@@ -746,7 +746,7 @@ func (d *decoder) unmarshalInlineTable(itable *unstable.Node, v reflect.Value) e
}
return d.unmarshalInlineTable(itable, elem)
default:
return unstable.NewParserError(itable.Data, "cannot store inline table in Go type %s", v.Kind())
return unstable.NewParserError(d.p.Raw(itable.Raw), "cannot store inline table in Go type %s", v.Kind())
}
it := itable.Children()
@@ -887,6 +887,11 @@ func init() {
}
func (d *decoder) unmarshalInteger(value *unstable.Node, v reflect.Value) error {
kind := v.Kind()
if kind == reflect.Float32 || kind == reflect.Float64 {
return d.unmarshalFloat(value, v)
}
i, err := parseInteger(value.Data)
if err != nil {
return err
@@ -894,7 +899,7 @@ func (d *decoder) unmarshalInteger(value *unstable.Node, v reflect.Value) error
var r reflect.Value
switch v.Kind() {
switch kind {
case reflect.Int64:
v.SetInt(i)
return nil
@@ -1034,15 +1039,9 @@ func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node
mv := v.MapIndex(mk)
set := false
if !mv.IsValid() {
if !mv.IsValid() || key.IsLast() {
set = true
mv = reflect.New(v.Type().Elem()).Elem()
} else {
if key.IsLast() {
var x interface{}
mv = reflect.ValueOf(&x).Elem()
set = true
}
}
nv, err := d.handleKeyValueInner(key, value, mv)
+23 -2
View File
@@ -2466,6 +2466,27 @@ func TestIssue807(t *testing.T) {
require.Equal(t, "foo", m.Name)
}
func TestIssue850(t *testing.T) {
data := make(map[string]string)
err := toml.Unmarshal([]byte("foo = {}"), &data)
require.Error(t, err)
}
func TestIssue851(t *testing.T) {
type Target struct {
Params map[string]string `toml:"params"`
}
content := "params = {a=\"1\",b=\"2\"}"
var target Target
err := toml.Unmarshal([]byte(content), &target)
require.NoError(t, err)
require.Equal(t, map[string]string{"a": "1", "b": "2"}, target.Params)
err = toml.Unmarshal([]byte(content), &target)
require.NoError(t, err)
require.Equal(t, map[string]string{"a": "1", "b": "2"}, target.Params)
}
func TestUnmarshalDecodeErrors(t *testing.T) {
examples := []struct {
desc string
@@ -2742,7 +2763,7 @@ world'`,
data: "a = \"aaaa\xE2\x80\x00\"",
},
{
desc: "invalid 4rd byte of 4-byte utf8 character in string with no escape sequence",
desc: "invalid 4th byte of 4-byte utf8 character in string with no escape sequence",
data: "a = \"aaaa\xF2\x81\x81\x00\"",
},
{
@@ -2758,7 +2779,7 @@ world'`,
data: "a = 'aaaa\xE2\x80\x00'",
},
{
desc: "invalid 4rd byte of 4-byte utf8 character in literal string",
desc: "invalid 4th byte of 4-byte utf8 character in literal string",
data: "a = 'aaaa\xF2\x81\x81\x00'",
},
{
+1 -1
View File
@@ -58,7 +58,7 @@ func (c *Iterator) Node() *Node {
// - Table and ArrayTable's children represent a dotted key (same as
// KeyValue, but without the first node being the value).
//
// When relevant, Raw describes the range of bytes this node is refering to in
// When relevant, Raw describes the range of bytes this node is referring to in
// the input document. Use Parser.Raw() to retrieve the actual bytes.
type Node struct {
Kind Kind
+3 -2
View File
@@ -132,12 +132,12 @@ func (p *Parser) NextExpression() bool {
}
// Expression returns a pointer to the node representing the last successfully
// parsed expresion.
// parsed expression.
func (p *Parser) Expression() *Node {
return p.builder.NodeAt(p.ref)
}
// Error returns any error that has occured during parsing.
// Error returns any error that has occurred during parsing.
func (p *Parser) Error() error {
return p.err
}
@@ -402,6 +402,7 @@ func (p *Parser) parseInlineTable(b []byte) (reference, []byte, error) {
// inline-table-keyvals = keyval [ inline-table-sep inline-table-keyvals ]
parent := p.builder.Push(Node{
Kind: InlineTable,
Raw: p.Range(b[:1]),
})
first := true