Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit 03f3462

Browse files
committed
Merge pull request #10 from kward/fix-protovers-parsing
Fix ProtocolVersion message parsing to support OS X 10.10.3.
2 parents f54c481 + cf7a8d3 commit 03f3462

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

client.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -279,24 +279,41 @@ func (c *ClientConn) SetPixelFormat(format *PixelFormat) error {
279279
return nil
280280
}
281281

282+
const pvLen = 12 // ProtocolVersion message length.
283+
284+
func parseProtocolVersion(pv []byte) (uint, uint, error) {
285+
var major, minor uint
286+
287+
if len(pv) < pvLen {
288+
return 0, 0, fmt.Errorf("ProtocolVersion message too short (%v < %v)", len(pv), pvLen)
289+
}
290+
291+
l, err := fmt.Sscanf(string(pv), "RFB %d.%d\n", &major, &minor)
292+
if l != 2 {
293+
return 0, 0, fmt.Errorf("error parsing ProtocolVersion.")
294+
}
295+
if err != nil {
296+
return 0, 0, err
297+
}
298+
299+
return major, minor, nil
300+
}
301+
282302
func (c *ClientConn) handshake() error {
283-
var protocolVersion [12]byte
303+
var protocolVersion [pvLen]byte
284304

285305
// 7.1.1, read the ProtocolVersion message sent by the server.
286306
if _, err := io.ReadFull(c.c, protocolVersion[:]); err != nil {
287307
return err
288308
}
289309

290-
var maxMajor, maxMinor uint8
291-
_, err := fmt.Sscanf(string(protocolVersion[:]), "RFB %d.%d\n", &maxMajor, &maxMinor)
310+
maxMajor, maxMinor, err := parseProtocolVersion(protocolVersion[:])
292311
if err != nil {
293312
return err
294313
}
295-
296314
if maxMajor < 3 {
297315
return fmt.Errorf("unsupported major version, less than 3: %d", maxMajor)
298316
}
299-
300317
if maxMinor < 8 {
301318
return fmt.Errorf("unsupported minor version, less than 8: %d", maxMinor)
302319
}

client_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,36 @@ func TestClient_LowMinorVersion(t *testing.T) {
6060
t.Fatalf("unexpected error: %s", err)
6161
}
6262
}
63+
64+
func TestParseProtocolVersion(t *testing.T) {
65+
tests := []struct {
66+
proto []byte
67+
major, minor uint
68+
isErr bool
69+
}{
70+
// Valid ProtocolVersion messages.
71+
{[]byte{82, 70, 66, 32, 48, 48, 51, 46, 48, 48, 56, 10}, 3, 8, false}, // RFB 003.008\n
72+
{[]byte{82, 70, 66, 32, 48, 48, 51, 46, 56, 56, 57, 10}, 3, 889, false}, // RFB 003.889\n -- OS X 10.10.3
73+
{[]byte{82, 70, 66, 32, 48, 48, 48, 46, 48, 48, 48, 10}, 0, 0, false}, // RFB 000.0000\n
74+
// Invalid messages.
75+
{[]byte{82, 70, 66, 32, 51, 46, 56, 10}, 0, 0, true}, // RFB 3.8\n -- too short; not zero padded
76+
{[]byte{82, 70, 66, 10}, 0, 0, true}, // RFB\n -- too short
77+
{[]byte{}, 0, 0, true}, // (empty) -- too short
78+
}
79+
80+
for _, tt := range tests {
81+
major, minor, err := parseProtocolVersion(tt.proto)
82+
if err != nil && !tt.isErr {
83+
t.Fatalf("parseProtocolVersion(%v) unexpected error %v", tt.proto, err)
84+
}
85+
if err == nil && tt.isErr {
86+
t.Fatalf("parseProtocolVersion(%v) expected error", tt.proto)
87+
}
88+
if major != tt.major {
89+
t.Errorf("parseProtocolVersion(%v) major = %v, want %v", tt.proto, major, tt.major)
90+
}
91+
if major != tt.major {
92+
t.Errorf("parseProtocolVersion(%v) minor = %v, want %v", tt.proto, minor, tt.minor)
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)