New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fmt: Sscanf accepts invalid boolean values #43306
Comments
looking at ends without an error: return false
} should be s.error(boolError)
return false
} Additionally, true and false parsers look wrong, case 't', 'T':
if s.accept("rR") && (!s.accept("uU") || !s.accept("eE")) {
s.error(boolError)
}
return true should be case 't', 'T':
if !s.accept("rR") || !s.accept("uU") || !s.accept("eE") {
s.error(boolError)
}
return true |
Can you provide a complete, runnable example? your example code and the expected input/output doesn't match |
package main
import "fmt"
func main() {
var val bool
err, n := fmt.Sscanf("true", "%t", &val)
fmt.Println("true:", val, n, err)
err, n = fmt.Sscanf("tBu", "%t", &val)
fmt.Println("tBu:", val, n, err)
err, n = fmt.Sscanf("trB", "%t", &val)
fmt.Println("trB:", val, n, err)
err, n = fmt.Sscanf("false", "%t", &val)
fmt.Println("false:", val, n, err)
err, n = fmt.Sscanf("fRl", "%t", &val)
fmt.Println("fRl:", val, n, err)
err, n = fmt.Sscanf("faR", "%t", &val)
fmt.Println("faR:", val, n, err)
err, n = fmt.Sscanf("foo", "%t", &val)
fmt.Println("foo:", val, n, err)
} |
I think you mixed up expected vs actual in the report. Additionally the value of
with output
The current logic accepts single letter
|
(updated the summary of the ticket, the outputs were the wrong way round) Fixing the single item logic may indeed be breaking, I had not realised. I guess the bigger issue, however, is that "garbage" will parse as a valid |
The Scanf code doesn't try to handle all possible errors, and there is a comment in there to that effect. Scanf isn't a strong input verifier, and isn't meant to be. You should only use it when you want to do something simple like read integers from the user's input command line. If you're looking for "true", look for "true", don't ask Scanf to verify it. Scanf is slow and tricky to use well for anything much beyond reading an int or float, so if you know the format of your input, you should use and/or write a proper lexer and/or parser. That said, a clean, simple fix to Scanf that can be more rigorous about parsing booleans would be welcome, but both those adjectives matter. (And you can't add any dependencies to the package.) Assuming of course that being rigorous won't break existing code. |
(For those following along at home, as I've said before, Scanf shouldn't even be in the library, being so much below the quality bar we would expect today. But the compatibility guarantee keeps it there.) |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Not checked 1.15.6 yet, sorry
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Tried to parse certain invalid boolean values using fmt.Sscanf and a "%t" format.
Using the following code to test certain input strings
What did you expect to see?
true: true 1
tBu: true syntax error scanning boolean 0
trB: true syntax error scanning boolean 0
false: false 1
fRl: false syntax error scanning boolean 0
faR: false syntax error scanning boolean 0
foo: false syntax error scanning boolean 0
What did you see instead?
true: true 1
tBu: true 1
trB: true syntax error scanning boolean 0
false: false 1
fRl: false 1
faR: false syntax error scanning boolean 0
foo: false 1
The text was updated successfully, but these errors were encountered: