Skip to content

Commit 3778fb9

Browse files
committed
fix: address Copilot review on PR #150
- ToInt/ToFloat reject NaN, +/-Inf, and out-of-range floats so invalid config surfaces deterministically instead of yielding implementation-dependent int values. - linelength.applyExclude now uses settings.ToStringSlice so rule state does not alias the caller's config slice; drops the local toStringSlice duplicate.
1 parent 8cee9dd commit 3778fb9

3 files changed

Lines changed: 24 additions & 24 deletions

File tree

internal/rules/linelength/rule.go

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func (r *Rule) applyStern(v any) error {
115115
}
116116

117117
func (r *Rule) applyExclude(v any) error {
118-
list, ok := toStringSlice(v)
118+
list, ok := settings.ToStringSlice(v)
119119
if !ok {
120120
return fmt.Errorf("line-length: exclude must be a list of strings, got %T", v)
121121
}
@@ -316,26 +316,6 @@ func headingLineNum(h *ast.Heading, f *lint.File) int {
316316
return 0
317317
}
318318

319-
// toStringSlice converts a value to []string. YAML decodes sequences as
320-
// []any with string elements.
321-
func toStringSlice(v any) ([]string, bool) {
322-
switch s := v.(type) {
323-
case []string:
324-
return s, true
325-
case []any:
326-
result := make([]string, 0, len(s))
327-
for _, item := range s {
328-
str, ok := item.(string)
329-
if !ok {
330-
return nil, false
331-
}
332-
result = append(result, str)
333-
}
334-
return result, true
335-
}
336-
return nil, false
337-
}
338-
339319
func isValidExclude(s string) bool {
340320
return s == "code-blocks" || s == "tables" || s == "urls"
341321
}

internal/rules/settings/settings.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,37 @@
88
// with consistent behavior and a single set of tests.
99
package settings
1010

11+
import "math"
12+
1113
// ToInt coerces v to an int when v is int, int64, or float64.
12-
// Float inputs are truncated toward zero. Other types (string, bool,
13-
// nil, slices) are rejected.
14+
// Float inputs are truncated toward zero. NaN, +/-Inf, and float
15+
// values outside the int range are rejected (ok=false).
1416
func ToInt(v any) (int, bool) {
1517
switch n := v.(type) {
1618
case int:
1719
return n, true
1820
case int64:
1921
return int(n), true
2022
case float64:
23+
if math.IsNaN(n) || math.IsInf(n, 0) {
24+
return 0, false
25+
}
26+
if n < math.MinInt || n > math.MaxInt {
27+
return 0, false
28+
}
2129
return int(n), true
2230
}
2331
return 0, false
2432
}
2533

2634
// ToFloat coerces v to a float64 when v is float64, int, or int64.
27-
// Other types are rejected.
35+
// NaN and +/-Inf are rejected. Other types are rejected.
2836
func ToFloat(v any) (float64, bool) {
2937
switch n := v.(type) {
3038
case float64:
39+
if math.IsNaN(n) || math.IsInf(n, 0) {
40+
return 0, false
41+
}
3142
return n, true
3243
case int:
3344
return float64(n), true

internal/rules/settings/settings_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package settings_test
22

33
import (
4+
"math"
45
"testing"
56

67
"github.com/jeduden/mdsmith/internal/rules/settings"
@@ -21,6 +22,11 @@ func TestToInt(t *testing.T) {
2122
{"float64-whole", 5.0, 5, true},
2223
{"float64-truncates", 3.9, 3, true},
2324
{"float64-negative-truncates", -2.7, -2, true},
25+
{"float64-nan-rejected", math.NaN(), 0, false},
26+
{"float64-posinf-rejected", math.Inf(1), 0, false},
27+
{"float64-neginf-rejected", math.Inf(-1), 0, false},
28+
{"float64-overflow-rejected", 1e20, 0, false},
29+
{"float64-underflow-rejected", -1e20, 0, false},
2430
{"string-rejected", "5", 0, false},
2531
{"bool-rejected", true, 0, false},
2632
{"nil-rejected", nil, 0, false},
@@ -46,6 +52,9 @@ func TestToFloat(t *testing.T) {
4652
{"float64-zero", 0.0, 0.0, true},
4753
{"int", 4, 4.0, true},
4854
{"int64", int64(9), 9.0, true},
55+
{"float64-nan-rejected", math.NaN(), 0, false},
56+
{"float64-posinf-rejected", math.Inf(1), 0, false},
57+
{"float64-neginf-rejected", math.Inf(-1), 0, false},
4958
{"string-rejected", "1.5", 0, false},
5059
{"bool-rejected", false, 0, false},
5160
{"nil-rejected", nil, 0, false},

0 commit comments

Comments
 (0)