Support byte order mark (#253)

Fixes #250
This commit is contained in:
Thomas Pelletier
2018-11-23 19:15:58 -05:00
committed by GitHub
parent b56e1b27b4
commit 539dd095b3
2 changed files with 49 additions and 0 deletions
+29
View File
@@ -333,10 +333,39 @@ func LoadBytes(b []byte) (tree *Tree, err error) {
err = errors.New(r.(string)) err = errors.New(r.(string))
} }
}() }()
if len(b) >= 4 && (hasUTF32BigEndianBOM4(b) || hasUTF32LittleEndianBOM4(b)) {
b = b[4:]
} else if len(b) >= 3 && hasUTF8BOM3(b) {
b = b[3:]
} else if len(b) >= 2 && (hasUTF16BigEndianBOM2(b) || hasUTF16LittleEndianBOM2(b)) {
b = b[2:]
}
tree = parseToml(lexToml(b)) tree = parseToml(lexToml(b))
return return
} }
func hasUTF16BigEndianBOM2(b []byte) bool {
return b[0] == 0xFE && b[1] == 0xFF
}
func hasUTF16LittleEndianBOM2(b []byte) bool {
return b[0] == 0xFF && b[1] == 0xFE
}
func hasUTF8BOM3(b []byte) bool {
return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF
}
func hasUTF32BigEndianBOM4(b []byte) bool {
return b[0] == 0x00 && b[1] == 0x00 && b[2] == 0xFE && b[3] == 0xFF
}
func hasUTF32LittleEndianBOM4(b []byte) bool {
return b[0] == 0xFF && b[1] == 0xFE && b[2] == 0x00 && b[3] == 0x00
}
// LoadReader creates a Tree from any io.Reader. // LoadReader creates a Tree from any io.Reader.
func LoadReader(reader io.Reader) (tree *Tree, err error) { func LoadReader(reader io.Reader) (tree *Tree, err error) {
inputBytes, err := ioutil.ReadAll(reader) inputBytes, err := ioutil.ReadAll(reader)
+20
View File
@@ -104,3 +104,23 @@ func TestTomlFromMap(t *testing.T) {
t.Fatal("hello should be 42, not", tree.Get("hello")) t.Fatal("hello should be 42, not", tree.Get("hello"))
} }
} }
func TestLoadBytesBOM(t *testing.T) {
payloads := [][]byte{
[]byte("\xFE\xFFhello=1"),
[]byte("\xFF\xFEhello=1"),
[]byte("\xEF\xBB\xBFhello=1"),
[]byte("\x00\x00\xFE\xFFhello=1"),
[]byte("\xFF\xFE\x00\x00hello=1"),
}
for _, data := range payloads {
tree, err := LoadBytes(data)
if err != nil {
t.Fatal("unexpected error:", err, "for:", data)
}
v := tree.Get("hello")
if v != int64(1) {
t.Fatal("hello should be 1, not", v)
}
}
}