Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate infinity values in data documents #1296

Merged
merged 21 commits into from Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions internal/types/document.go
Expand Up @@ -93,6 +93,10 @@ func NewDocument(pairs ...any) (*Document, error) {
}
}

if err := doc.ValidateCmd(); err != nil {
return nil, fmt.Errorf("types.NewDocument: %w", err)
}

AlekSi marked this conversation as resolved.
Show resolved Hide resolved
return doc, nil
}

Expand Down
32 changes: 29 additions & 3 deletions internal/types/document_validation.go
Expand Up @@ -16,6 +16,7 @@ package types

import (
"fmt"
"math"
"strings"
"unicode/utf8"
)
Expand All @@ -38,9 +39,9 @@ func (e *ValidationError) Error() string {
// ValidateData checks if the document represents a valid "data document".
// If the document is not valid it returns *ValidationError.
func (d *Document) ValidateData() error {
// The following block should be used to checks that keys are valid.
// All further key related validation rules should be added here.
noisersup marked this conversation as resolved.
Show resolved Hide resolved
for _, key := range d.keys {
// The following block should be used to checks that keys and values are valid.
// All further validation rules should be added here.
for key, v := range d.m {
// Tests for this case are in `dance`.
if !utf8.ValidString(key) {
return newValidationError(fmt.Errorf("invalid key: %q (not a valid UTF-8 string)", key))
Expand All @@ -50,7 +51,32 @@ func (d *Document) ValidateData() error {
if strings.Contains(key, "$") {
return newValidationError(fmt.Errorf("invalid key: %q (key must not contain $)", key))
}

if v, ok := v.(float64); ok {
switch {
case math.IsInf(v, 0):
return newValidationError(fmt.Errorf("invalid value: %f (infinity values are not allowed)", v))
case math.IsNaN(v):
return newValidationError(fmt.Errorf("invalid value: %f (NaN values are not allowed)", v))
}
}
}

return nil
}

// ValidateCmd checks if the document represents a valid "command document".
// If the document is not valid it returns *ValidationError.
func (d *Document) ValidateCmd() error {
for _, v := range d.m {
if v, ok := v.(float64); ok {
switch {
case math.IsInf(v, 0):
return newValidationError(fmt.Errorf("invalid value: %f (infinity values are not allowed)", v))
case math.IsNaN(v):
return newValidationError(fmt.Errorf("invalid value: %f (NaN values are not allowed)", v))
}
}
}
return nil
}
13 changes: 13 additions & 0 deletions internal/types/document_validation_test.go
Expand Up @@ -16,6 +16,7 @@ package types

import (
"errors"
"math"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -46,6 +47,18 @@ func TestDocumentValidateData(t *testing.T) {
doc: must.NotFail(NewDocument("$v", "bar")),
reason: errors.New(`invalid key: "$v" (key must not contain $)`),
},
"Inf+": {
doc: must.NotFail(NewDocument("v", math.Inf(1))),
reason: errors.New(`invalid value: +Inf (infinity values are not allowed)`),
rumyantseva marked this conversation as resolved.
Show resolved Hide resolved
},
"Inf-": {
doc: must.NotFail(NewDocument("v", math.Inf(-1))),
reason: errors.New(`invalid value: -Inf (infinity values are not allowed)`),
},
"NaN": {
doc: must.NotFail(NewDocument("v", math.NaN())),
reason: errors.New(`invalid value: NaN (NaN values are not allowed)`),
},
} {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
Expand Down