Fixes #32 : Ensure keys are correctly parsed

This commit is contained in:
Thomas Pelletier
2014-12-06 14:16:42 +01:00
parent 543444f747
commit 2f2f28631b
4 changed files with 20 additions and 15 deletions
+5 -2
View File
@@ -138,7 +138,7 @@ func (l *tomlLexer) lexVoid() tomlLexStateFn {
return l.lexRvalue return l.lexRvalue
} }
if isKeyChar(next) { if isKeyStartChar(next) {
return l.lexKey return l.lexKey
} }
@@ -250,7 +250,10 @@ func (l *tomlLexer) lexComma() tomlLexStateFn {
func (l *tomlLexer) lexKey() tomlLexStateFn { func (l *tomlLexer) lexKey() tomlLexStateFn {
l.ignore() l.ignore()
for isKeyChar(l.next()) { for r := l.next(); isKeyChar(r); r = l.next() {
if (r == '#') {
return l.errorf("keys cannot contain # character")
}
} }
l.backup() l.backup()
l.emit(tokenKey) l.emit(tokenKey)
+6 -9
View File
@@ -118,19 +118,16 @@ func TestBasicKeyAndEqual(t *testing.T) {
func TestKeyWithSharpAndEqual(t *testing.T) { func TestKeyWithSharpAndEqual(t *testing.T) {
testFlow(t, "key#name = 5", []token{ testFlow(t, "key#name = 5", []token{
token{Position{1, 1}, tokenKey, "key#name"}, token{Position{1, 1}, tokenError, "keys cannot contain # character"},
token{Position{1, 10}, tokenEqual, "="},
token{Position{1, 12}, tokenInteger, "5"},
token{Position{1, 13}, tokenEOF, ""},
}) })
} }
func TestKeyWithSymbolsAndEqual(t *testing.T) { func TestKeyWithSymbolsAndEqual(t *testing.T) {
testFlow(t, "~!@#$^&*()_+-`1234567890[]\\|/?><.,;:' = 5", []token{ testFlow(t, "~!@$^&*()_+-`1234567890[]\\|/?><.,;:' = 5", []token{
token{Position{1, 1}, tokenKey, "~!@#$^&*()_+-`1234567890[]\\|/?><.,;:'"}, token{Position{1, 1}, tokenKey, "~!@$^&*()_+-`1234567890[]\\|/?><.,;:'"},
token{Position{1, 39}, tokenEqual, "="}, token{Position{1, 38}, tokenEqual, "="},
token{Position{1, 41}, tokenInteger, "5"}, token{Position{1, 40}, tokenInteger, "5"},
token{Position{1, 42}, tokenEOF, ""}, token{Position{1, 41}, tokenEOF, ""},
}) })
} }
+2 -2
View File
@@ -54,9 +54,9 @@ func TestSimpleKV(t *testing.T) {
// NOTE: from the BurntSushi test suite // NOTE: from the BurntSushi test suite
// NOTE: this test is pure evil due to the embedded '.' // NOTE: this test is pure evil due to the embedded '.'
func TestSpecialKV(t *testing.T) { func TestSpecialKV(t *testing.T) {
tree, err := Load("~!@#$^&*()_+-`1234567890[]\\|/?><.,;: = 1") tree, err := Load("~!@$^&*()_+-`1234567890[]\\|/?><.,;: = 1")
assertTree(t, tree, err, map[string]interface{}{ assertTree(t, tree, err, map[string]interface{}{
"~!@#$^&*()_+-`1234567890[]\\|/?><.,;:": int64(1), "~!@$^&*()_+-`1234567890[]\\|/?><.,;:": int64(1),
}) })
} }
+7 -2
View File
@@ -117,11 +117,16 @@ func isAlphanumeric(r rune) bool {
} }
func isKeyChar(r rune) bool { func isKeyChar(r rune) bool {
// "Keys start with the first non-whitespace character and end with the last // Keys start with the first character that isn't whitespace or [ and end
// non-whitespace character before the equals sign." // with the last non-whitespace character before the equals sign. Keys
// cannot contain a # character."
return !(isSpace(r) || r == '\r' || r == '\n' || r == eof || r == '=') return !(isSpace(r) || r == '\r' || r == '\n' || r == eof || r == '=')
} }
func isKeyStartChar(r rune) bool {
return !(isSpace(r) || r == '\r' || r == '\n' || r == eof || r == '[')
}
func isDigit(r rune) bool { func isDigit(r rune) bool {
return unicode.IsNumber(r) return unicode.IsNumber(r)
} }