Patch ASN.1 BER encoding of integers and length + unit tests
This commit is contained in:
parent
2a844bd559
commit
a08be6b395
3 changed files with 160 additions and 10 deletions
|
@ -223,19 +223,33 @@ func parseInt64(bytes []byte) (ret int64, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func sizeInt64(i int64) (size int) {
|
func sizeInt64(i int64) int {
|
||||||
for ; i != 0 || size == 0; i >>= 8 {
|
n := 1
|
||||||
size++
|
|
||||||
}
|
for i > 127 {
|
||||||
return
|
n++
|
||||||
|
i >>= 8
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeInt64(bytes *Bytes, i int64) (size int) {
|
for i < -128 {
|
||||||
for ; i != 0 || size == 0; i >>= 8 { // Write at least one byte even if the value is 0
|
n++
|
||||||
bytes.writeBytes([]byte{byte(i)})
|
i >>= 8
|
||||||
size++
|
|
||||||
}
|
}
|
||||||
return
|
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeInt64(bytes *Bytes, i int64) int {
|
||||||
|
n := sizeInt64(i)
|
||||||
|
buf := [8]byte{}
|
||||||
|
|
||||||
|
for j := 0; j < n; j++ {
|
||||||
|
b := i >> uint((n-1-j)*8)
|
||||||
|
buf[j] = byte(b)
|
||||||
|
}
|
||||||
|
bytes.writeBytes(buf[:n])
|
||||||
|
|
||||||
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseInt treats the given bytes as a big-endian, signed integer and returns
|
// parseInt treats the given bytes as a big-endian, signed integer and returns
|
||||||
|
@ -713,7 +727,13 @@ func writeTagAndLength(bytes *Bytes, t TagAndLength) (size int) {
|
||||||
panic("Can't have a negative length")
|
panic("Can't have a negative length")
|
||||||
|
|
||||||
} else if t.Length >= 128 {
|
} else if t.Length >= 128 {
|
||||||
lengthBytes := writeInt64(bytes, int64(t.Length))
|
lengthBytes := 0
|
||||||
|
val := t.Length
|
||||||
|
for val > 0 {
|
||||||
|
lengthBytes++
|
||||||
|
bytes.writeBytes([]byte{byte(val & 0xff)})
|
||||||
|
val >>= 8
|
||||||
|
}
|
||||||
bytes.writeBytes([]byte{byte(0x80 | byte(lengthBytes))})
|
bytes.writeBytes([]byte{byte(0x80 | byte(lengthBytes))})
|
||||||
size += lengthBytes + 1
|
size += lengthBytes + 1
|
||||||
|
|
||||||
|
|
54
goldap/asn1_test.go
Normal file
54
goldap/asn1_test.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package message
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"bytes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSizeInt64(t *testing.T) {
|
||||||
|
s := sizeInt64(0)
|
||||||
|
if s != 1 {
|
||||||
|
t.Errorf("computed size is %d, expected 1", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
s = sizeInt64(127)
|
||||||
|
if s != 1 {
|
||||||
|
t.Errorf("computed size is %d, expected 1", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
s = sizeInt64(128)
|
||||||
|
if s != 2 {
|
||||||
|
t.Errorf("computed size is %d, expected 2", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
s = sizeInt64(50000)
|
||||||
|
if s != 3 {
|
||||||
|
t.Errorf("computed size is %d, expected 3", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
s = sizeInt64(-12345)
|
||||||
|
if s != 2 {
|
||||||
|
t.Errorf("computed size is %d, expected 2", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteInt64(t *testing.T) {
|
||||||
|
vtests := []int64{0, 127, 128, 50000, -12345}
|
||||||
|
expsize := []int{1, 1, 2, 3, 2}
|
||||||
|
expresult := [][]byte{{0x00}, {0x7F}, {0x00, 0x80}, {0x00, 0xc3, 0x50}, {0xcf, 0xc7}}
|
||||||
|
|
||||||
|
for idx, v := range vtests {
|
||||||
|
fs := sizeInt64(v)
|
||||||
|
b := NewBytes(fs, make([]byte, fs))
|
||||||
|
t.Log("computing", v)
|
||||||
|
s := writeInt64(b, v)
|
||||||
|
if s != expsize[idx] {
|
||||||
|
t.Errorf("computed size is %d, expected %d", s, expsize[idx])
|
||||||
|
}
|
||||||
|
if !bytes.Equal(b.Bytes(), expresult[idx]) {
|
||||||
|
t.Errorf("wrong computed bytes, got %v, expected %v", b.Bytes(), expresult[idx])
|
||||||
|
}
|
||||||
|
a, e := parseInt64(b.Bytes())
|
||||||
|
t.Log("parse", a, e)
|
||||||
|
}
|
||||||
|
}
|
76
goldap/message_test.go
Normal file
76
goldap/message_test.go
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
package message
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func toHex(b []byte) (r string) {
|
||||||
|
r = "[ "
|
||||||
|
for _, e := range b {
|
||||||
|
r += fmt.Sprintf("0x%x ", e)
|
||||||
|
}
|
||||||
|
return r + "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMessageID(t *testing.T) {
|
||||||
|
m := NewLDAPMessageWithProtocolOp(UnbindRequest{})
|
||||||
|
m.SetMessageID(128)
|
||||||
|
buf, err := m.Write()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("marshalling failed with %v", err)
|
||||||
|
}
|
||||||
|
t.Logf("%v", toHex(buf.Bytes()))
|
||||||
|
|
||||||
|
ret, err := ReadLDAPMessage(NewBytes(0, buf.Bytes()))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unmarshalling failed with %v", err)
|
||||||
|
}
|
||||||
|
if _, ok := ret.ProtocolOp().(UnbindRequest); !ok {
|
||||||
|
t.Errorf("should be an unbind request")
|
||||||
|
}
|
||||||
|
if ret.MessageID() != 128 {
|
||||||
|
t.Errorf("Expect message id 128, got %d", ret.MessageID())
|
||||||
|
}
|
||||||
|
t.Log("Done, marshal/unmarshall worked")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSearchEntry(t *testing.T) {
|
||||||
|
m := NewLDAPMessageWithProtocolOp(SearchResultEntry{
|
||||||
|
objectName:"cn=êige€nbgtz,ou=users,dc=deuxfleurs,dc=fr",
|
||||||
|
attributes: PartialAttributeList{
|
||||||
|
PartialAttribute{
|
||||||
|
type_:"displayname",
|
||||||
|
vals:[]AttributeValue{"êiGe€NBgTZ"},
|
||||||
|
},
|
||||||
|
PartialAttribute{
|
||||||
|
type_:"objectclass",
|
||||||
|
vals:[]AttributeValue{"inetOrgPerson"},
|
||||||
|
},
|
||||||
|
PartialAttribute{
|
||||||
|
type_:"objectclass",
|
||||||
|
vals:[]AttributeValue{"organizationalPerson"},
|
||||||
|
},
|
||||||
|
PartialAttribute{
|
||||||
|
type_:"objectclass",
|
||||||
|
vals:[]AttributeValue{"person"},
|
||||||
|
},
|
||||||
|
PartialAttribute{
|
||||||
|
type_:"objectclass",
|
||||||
|
vals:[]AttributeValue{"top"},
|
||||||
|
},
|
||||||
|
PartialAttribute{
|
||||||
|
type_:"structuralobjectclass",
|
||||||
|
vals:[]AttributeValue{"inetOrgPerson"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
m.SetMessageID(24)
|
||||||
|
buf, err := m.Write()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("marshalling failed with %v", err)
|
||||||
|
}
|
||||||
|
if buf.Bytes()[0] != 0x30 {
|
||||||
|
t.Logf("Malformed message: %v", toHex(buf.Bytes()))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue