{"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"},
{"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence.
{"%.[]", SE{}, "%!](BADINDEX)"}, // Issue 10675
+ {"%.-3d", SE{42}, "%!-(int=42)3d"}, // TODO: Should this set return better error messages?
+ {"%2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
+ {"%-2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
+ {"%.2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
}
func TestReorder(t *testing.T) {
out string
}{
{"%*d", args(4, 42), " 42"},
+ {"%-*d", args(4, 42), "42 "},
+ {"%*d", args(-4, 42), "42 "},
+ {"%-*d", args(-4, 42), "42 "},
{"%.*d", args(4, 42), "0042"},
{"%*.*d", args(8, 4, 42), " 0042"},
{"%0*d", args(4, 42), "0042"},
- {"%-*d", args(4, 42), "42 "},
// erroneous
{"%*d", args(nil, 42), "%!(BADWIDTH)42"},
+ {"%*d", args(int(1e7), 42), "%!(BADWIDTH)42"},
+ {"%*d", args(int(-1e7), 42), "%!(BADWIDTH)42"},
{"%.*d", args(nil, 42), "%!(BADPREC)42"},
+ {"%.*d", args(-1, 42), "%!(BADPREC)42"},
+ {"%.*d", args(int(1e7), 42), "%!(BADPREC)42"},
{"%*d", args(5, "foo"), "%!d(string= foo)"},
{"%*% %d", args(20, 5), "% 5"},
{"%*", args(4), "%!(NOVERB)"},
return val
}
+// tooLarge reports whether the magnitude of the integer is
+// too large to be used as a formatting width or precision.
+func tooLarge(x int) bool {
+ const max int = 1e6
+ return x > max || x < -max
+}
+
// parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present.
func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
if start >= end {
return 0, false, end
}
for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
- const maxInt32 = 1<<31 - 1 // 31 bits is plenty for a width.
- max := maxInt32/10 - 1
- if num > max {
+ if tooLarge(num) {
return 0, false, end // Overflow; crazy long number most likely.
}
num = num*10 + int(s[newi]-'0')
if argNum < len(a) {
num, isInt = a[argNum].(int)
newArgNum = argNum + 1
+ if tooLarge(num) {
+ num = 0
+ isInt = false
+ }
}
return
}
if i < end && format[i] == '*' {
i++
p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
+
if !p.fmt.widPresent {
p.buf.Write(badWidthBytes)
}
+
+ // We have a negative width, so take its value and ensure
+ // that the minus flag is set
+ if p.fmt.wid < 0 {
+ p.fmt.wid = -p.fmt.wid
+ p.fmt.minus = true
+ }
afterIndex = false
} else {
p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
if i < end && format[i] == '*' {
i++
p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
+ // Negative precision arguments don't make sense
+ if p.fmt.prec < 0 {
+ p.fmt.prec = 0
+ p.fmt.precPresent = false
+ }
if !p.fmt.precPresent {
p.buf.Write(badPrecBytes)
}