One spelling for an unvalidated builtin arg, and say what the hold buys

float's prep still swallowed ParseFloat's error three lines from the atoi that
had just been changed to report one — two spellings of "parse an arg the check
already validated". atof reports it the same way.

The README paragraph said a reference reaching through an operand is caught,
which the narrowed fence no longer does and should not: it says what the hold
pins instead. Restored the why the trimmed comment in expand had carried.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
M
2026-08-31 15:05:52 +02:00
committed by lilleman-tw
parent 027d5c33fc
commit f949550515
3 changed files with 16 additions and 7 deletions
+10 -3
View File
@@ -48,9 +48,7 @@ var builtins = map[string]builtin{
return func(s *session, _ string, _ []string) string { return strconv.Itoa(lo + s.IntN(span)) }
}},
"float": {arity: 3, check: floatArgs, prep: func(a []string) callFn {
lo, _ := strconv.ParseFloat(a[0], 64)
hi, _ := strconv.ParseFloat(a[1], 64)
dp := atoi(a[2])
lo, hi, dp := atof(a[0]), atof(a[1]), atoi(a[2])
return func(s *session, _ string, _ []string) string {
return strconv.FormatFloat(lo+s.Float64()*(hi-lo), 'f', dp, 64)
}
@@ -104,6 +102,15 @@ func atoi(s string) int {
return n
}
// atof is atoi for a float arg, and reports an unvalidated one the same way.
func atof(s string) float64 {
f, err := strconv.ParseFloat(s, 64)
if err != nil {
panic(fmt.Sprintf("fakes: builtin arg %q reached prep unvalidated: %v", s, err))
}
return f
}
func randBytes(r rng, n int) []byte {
b := make([]byte, n)
for i := range b {