Commit 8331f19d authored by Nodir Turakulov's avatar Nodir Turakulov Committed by Rob Pike

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 <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarRob Pike <r@golang.org>
parent b8903339
...@@ -1108,6 +1108,10 @@ func (s *ss) advance(format string) (i int) { ...@@ -1108,6 +1108,10 @@ func (s *ss) advance(format string) (i int) {
// in the input. // in the input.
inputc := s.getRune() inputc := s.getRune()
if inputc == eof { if inputc == eof {
if wasNewline {
// Newlines are mandatory.
return -1
}
return return
} }
if !isSpace(inputc) { if !isSpace(inputc) {
...@@ -1148,17 +1152,18 @@ func (s *ss) doScanf(format string, a []interface{}) (numProcessed int, err erro ...@@ -1148,17 +1152,18 @@ func (s *ss) doScanf(format string, a []interface{}) (numProcessed int, err erro
end := len(format) - 1 end := len(format) - 1
// We process one item per non-trivial format // We process one item per non-trivial format
for i := 0; i <= end; { for i := 0; i <= end; {
w := s.advance(format[i:]) switch w := s.advance(format[i:]); {
if w > 0 { case w > 0:
i += w i += w
continue 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] != '%' { 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 // Otherwise at EOF; "too many operands" error handled below
break break
} }
......
...@@ -1114,14 +1114,22 @@ func TestScanfNewlineMatchFormat(t *testing.T) { ...@@ -1114,14 +1114,22 @@ func TestScanfNewlineMatchFormat(t *testing.T) {
count int count int
ok bool 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}, {"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}, {"space-newline in input", "1 \n2", "%d %d", 1, false},
{"newline in format", "1 2", "%d\n%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 format", "1 2", "%d \n%d", 1, false},
{"space-newline in both", "1 \n2", "%d \n%d", 2, true}, {"space-newline in both", "1 \n2", "%d \n%d", 2, true},
{"extra space in format", "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}, {"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 { for _, test := range tests {
n, err := Sscanf(test.text, test.format, &a, &b) n, err := Sscanf(test.text, test.format, &a, &b)
......
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