bug fix: allow folder names up to length 64 in leveldb

When extracting a folder name from the byte slices used as database
keys, bytes.IndexByte() is used to find and remove trailing 0 bytes.
In case the folder name is 64 bytes long, bytes.IndexByte() returns
-1.  Before this change, syncthing crashed in this case with an
out-of-bounds slice access.

The commit fixes the problem and also introduces a test case which
checks for the presence of the bug.
This commit is contained in:
Jochen Voss
2014-10-07 14:05:04 +01:00
committed by Jochen Voss (voss@sushi)
parent 30aabf1da9
commit d297f9e032
2 changed files with 89 additions and 25 deletions

View File

@@ -82,52 +82,55 @@ type dbWriter interface {
Delete([]byte)
}
/*
keyTypeDevice (1 byte)
folder (64 bytes)
device (32 bytes)
name (variable size)
|
scanner.File
keyTypeGlobal (1 byte)
folder (64 bytes)
name (variable size)
|
[]fileVersion (sorted)
*/
// deviceKey returns a byte slice encoding the following information:
// keyTypeDevice (1 byte)
// folder (64 bytes)
// device (32 bytes)
// name (variable size)
func deviceKey(folder, device, file []byte) []byte {
k := make([]byte, 1+64+32+len(file))
k[0] = keyTypeDevice
if len(folder) > 64 {
panic("folder name too long")
}
copy(k[1:], []byte(folder))
copy(k[1+64:], device[:])
copy(k[1+64+32:], []byte(file))
return k
}
func globalKey(folder, file []byte) []byte {
k := make([]byte, 1+64+len(file))
k[0] = keyTypeGlobal
copy(k[1:], []byte(folder))
copy(k[1+64:], []byte(file))
return k
}
func deviceKeyName(key []byte) []byte {
return key[1+64+32:]
}
func deviceKeyFolder(key []byte) []byte {
folder := key[1 : 1+64]
izero := bytes.IndexByte(folder, 0)
if izero < 0 {
return folder
}
return folder[:izero]
}
func deviceKeyDevice(key []byte) []byte {
return key[1+64 : 1+64+32]
}
// globalKey returns a byte slice encoding the following information:
// keyTypeGlobal (1 byte)
// folder (64 bytes)
// name (variable size)
func globalKey(folder, file []byte) []byte {
k := make([]byte, 1+64+len(file))
k[0] = keyTypeGlobal
if len(folder) > 64 {
panic("folder name too long")
}
copy(k[1:], []byte(folder))
copy(k[1+64:], []byte(file))
return k
}
func globalKeyName(key []byte) []byte {
return key[1+64:]
}
@@ -135,6 +138,9 @@ func globalKeyName(key []byte) []byte {
func globalKeyFolder(key []byte) []byte {
folder := key[1 : 1+64]
izero := bytes.IndexByte(folder, 0)
if izero < 0 {
return folder
}
return folder[:izero]
}