Commit 3e3ed5d9 authored by Rob Pike's avatar Rob Pike

fmt: one bad index shouldn't spoil them all

In an indexed verb such as %[3]d, if the index is out of range, don't
skip processing the rest of the verbs. The bug was that the bad
index set a bit for the whole format instead of just the verb.

Ok for 1.2 because this is a bug in a 1.2 feature.

Fixes #6434

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/13632058
parent d00fb0a1
...@@ -589,6 +589,8 @@ var reorderTests = []struct { ...@@ -589,6 +589,8 @@ var reorderTests = []struct {
{"%3.[2]d", SE{7}, "%!d(BADINDEX)"}, {"%3.[2]d", SE{7}, "%!d(BADINDEX)"},
{"%.[2]d", SE{7}, "%!d(BADINDEX)"}, {"%.[2]d", SE{7}, "%!d(BADINDEX)"},
{"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"}, {"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"},
{"%[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.
} }
func TestReorder(t *testing.T) { func TestReorder(t *testing.T) {
......
...@@ -118,7 +118,7 @@ type pp struct { ...@@ -118,7 +118,7 @@ type pp struct {
value reflect.Value value reflect.Value
// reordered records whether the format string used argument reordering. // reordered records whether the format string used argument reordering.
reordered bool reordered bool
// goodArgNum records whether all reordering directives were valid. // goodArgNum records whether the most recent reordering directive was valid.
goodArgNum bool goodArgNum bool
runeBuf [utf8.UTFMax]byte runeBuf [utf8.UTFMax]byte
fmt fmt fmt fmt
...@@ -1036,7 +1036,7 @@ func intFromArg(a []interface{}, argNum int) (num int, isInt bool, newArgNum int ...@@ -1036,7 +1036,7 @@ func intFromArg(a []interface{}, argNum int) (num int, isInt bool, newArgNum int
// up to the closing paren, if present, and whether the number parsed // up to the closing paren, if present, and whether the number parsed
// ok. The bytes to consume will be 1 if no closing paren is present. // ok. The bytes to consume will be 1 if no closing paren is present.
func parseArgNumber(format string) (index int, wid int, ok bool) { func parseArgNumber(format string) (index int, wid int, ok bool) {
// Find closing parenthesis // Find closing bracket.
for i := 1; i < len(format); i++ { for i := 1; i < len(format); i++ {
if format[i] == ']' { if format[i] == ']' {
width, ok, newi := parsenum(format, 1, i) width, ok, newi := parsenum(format, 1, i)
...@@ -1070,8 +1070,8 @@ func (p *pp) doPrintf(format string, a []interface{}) { ...@@ -1070,8 +1070,8 @@ func (p *pp) doPrintf(format string, a []interface{}) {
argNum := 0 // we process one argument per non-trivial format argNum := 0 // we process one argument per non-trivial format
afterIndex := false // previous item in format was an index like [3]. afterIndex := false // previous item in format was an index like [3].
p.reordered = false p.reordered = false
p.goodArgNum = true
for i := 0; i < end; { for i := 0; i < end; {
p.goodArgNum = true
lasti := i lasti := i
for i < end && format[i] != '%' { for i < end && format[i] != '%' {
i++ i++
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment