From: Nodir Turakulov Date: Wed, 21 Oct 2015 18:09:00 +0000 (-0700) Subject: fmt: check newline in the end of input X-Git-Tag: go1.6beta1~332 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=8331f19d9700457d74bf377755ca270a32d2faa3;p=gostls13.git fmt: check newline in the end of input Sscanf doc says: Newlines in the input must match newlines in the format. However Sscanf didn't check newline in the end of input (EOF). A test for the case is broken. * check newline in EOF * fix the test * slightly simplify ss.doScanf Fixes #12788 Change-Id: Iaf6b7d81324a72e557543ac22ecea5cecb72e0d6 Reviewed-on: https://go-review.googlesource.com/16165 Run-TryBot: Rob Pike TryBot-Result: Gobot Gobot Reviewed-by: Rob Pike --- diff --git a/src/fmt/scan.go b/src/fmt/scan.go index 4618ed4a82..553deb4327 100644 --- a/src/fmt/scan.go +++ b/src/fmt/scan.go @@ -1108,6 +1108,10 @@ func (s *ss) advance(format string) (i int) { // in the input. inputc := s.getRune() if inputc == eof { + if wasNewline { + // Newlines are mandatory. + return -1 + } return } if !isSpace(inputc) { @@ -1148,17 +1152,18 @@ func (s *ss) doScanf(format string, a []interface{}) (numProcessed int, err erro end := len(format) - 1 // We process one item per non-trivial format for i := 0; i <= end; { - w := s.advance(format[i:]) - if w > 0 { + switch w := s.advance(format[i:]); { + case w > 0: i += w continue + case w < 0: + // Can't advance format. Why not? + s.errorString("input does not match format") } - // Either we failed to advance, we have a percent character, or we ran out of input. + + // Either we have a percent character, or we ran out of input. + if format[i] != '%' { - // Can't advance format. Why not? - if w < 0 { - s.errorString("input does not match format") - } // Otherwise at EOF; "too many operands" error handled below break } diff --git a/src/fmt/scan_test.go b/src/fmt/scan_test.go index 7ac74dcb4b..bcc2844ef0 100644 --- a/src/fmt/scan_test.go +++ b/src/fmt/scan_test.go @@ -1114,14 +1114,22 @@ func TestScanfNewlineMatchFormat(t *testing.T) { count int ok bool }{ - {"newline in both", "1\n2", "%d\n%d\n", 2, true}, + {"newline in both", "1\n2", "%d\n%d", 2, true}, {"newline in input", "1\n2", "%d %d", 1, false}, + {"extra newline in format", "1\n2", "%d\n%d\n", 2, false}, + {"newline-newline in both", "1\n\n2", "%d\n\n%d", 2, true}, + {"newline-newline in format", "1\n2", "%d\n\n%d", 1, false}, + {"newline-newline in input", "1\n\n2", "%d\n%d", 1, false}, {"space-newline in input", "1 \n2", "%d %d", 1, false}, {"newline in format", "1 2", "%d\n%d", 1, false}, {"space-newline in format", "1 2", "%d \n%d", 1, false}, {"space-newline in both", "1 \n2", "%d \n%d", 2, true}, {"extra space in format", "1\n2", "%d\n %d", 2, true}, {"two extra spaces in format", "1\n2", "%d \n %d", 2, true}, + {"newline start in both", "\n1 2", "\n%d %d", 2, true}, + {"newline start in format", "1 2", "\n%d %d", 0, false}, + {"newline start in input", "\n1 2", "%d %d", 0, false}, + {"space-newline start in input", " \n1 2", "\n%d %d", 2, true}, } for _, test := range tests { n, err := Sscanf(test.text, test.format, &a, &b)