diff --git a/lib/srv/db/sqlserver/protocol/fixtures/packets.go b/lib/srv/db/sqlserver/protocol/fixtures/packets.go index 8440090a998f3..9fc711b13685c 100644 --- a/lib/srv/db/sqlserver/protocol/fixtures/packets.go +++ b/lib/srv/db/sqlserver/protocol/fixtures/packets.go @@ -93,7 +93,8 @@ var ( // partially Length-prefixed Bytes request, as described here: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/3f983fde-0509-485a-8c40-a9fa6679a828 func RPCClientPartiallyLength(length uint64, chunks uint64) []byte { packet := []byte{ - 0x03, 0x01, 0x00, 0x00, // Length placeholder + 0x03, 0x01, + 0x00, 0x00, // Length placeholder 0x00, 0x00, 0x01, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, @@ -104,22 +105,32 @@ func RPCClientPartiallyLength(length uint64, chunks uint64) []byte { 0x00, 0x00, 0x00, 0x00, 0x00, // NVARCHARTYPE flags } + // NVARCHARTYPE must have even length + if length%2 != 0 { + length += 1 + } + packet = binary.LittleEndian.AppendUint64(packet, length) if length > 0 && chunks > 1 { chunkSize := length / chunks rem := length - for rem > 0 { + for i := uint64(0); i < chunks-1; i++ { packet = binary.LittleEndian.AppendUint32(packet, uint32(chunkSize)) data := make([]byte, chunkSize) packet = append(packet, data...) rem -= chunkSize } + + // Last chunk will contain the remaining data. + packet = binary.LittleEndian.AppendUint32(packet, uint32(rem)) + data := make([]byte, rem) + packet = append(packet, data...) } // PLP_TERMINATOR packet = append(packet, []byte{0x00, 0x00, 0x00, 0x00}...) - packet[3] = byte(len(packet)) + binary.BigEndian.PutUint16(packet[2:], uint16(len(packet))) return packet }