screen: fix framebuffer height parse and stray byte consume
Two RFB protocol bugs in the /screen client: 1. ServerInit parsed framebuffer-height from byte offset 1 instead of 2. RFB 3.8 ServerInit is width@0-1, height@2-3; u16be(b,1) mixes the low byte of width with the high byte of height. The wrong height went into the initial non-incremental FramebufferUpdate- Request; neatvnc feeds the client's width/height straight into pixman_region_union_rect un-clipped (src/server.c), so an out-of-range height corrupts the server damage region and pixman reports 'Invalid rectangle passed'. 2. FramebufferUpdate handler had a stray drainTo(1) after the 3-byte padding+nRects header, consuming the first byte of the first rectangle and desyncing every update. Closes #128
This commit is contained in:
parent
08913484cc
commit
a5ef10c10c
1 changed files with 4 additions and 5 deletions
|
|
@ -467,7 +467,8 @@ canvas { display: block; cursor: default; }
|
||||||
case 'server-init': {
|
case 'server-init': {
|
||||||
const b = drainTo(24);
|
const b = drainTo(24);
|
||||||
if (!b) return false;
|
if (!b) return false;
|
||||||
fbW = u16be(b, 0); fbH = u16be(b, 1);
|
// RFB ServerInit: width @ bytes 0-1, height @ bytes 2-3.
|
||||||
|
fbW = u16be(b, 0); fbH = u16be(b, 2);
|
||||||
// pixel format: bpp=b[4], depth=b[5], big-endian=b[6], true-colour=b[7]
|
// pixel format: bpp=b[4], depth=b[5], big-endian=b[6], true-colour=b[7]
|
||||||
// red/green/blue max/shift at b[8..17]
|
// red/green/blue max/shift at b[8..17]
|
||||||
pixelFormat = {
|
pixelFormat = {
|
||||||
|
|
@ -493,12 +494,10 @@ canvas { display: block; cursor: default; }
|
||||||
if (!b) return false;
|
if (!b) return false;
|
||||||
const msgType = b[0];
|
const msgType = b[0];
|
||||||
if (msgType === 0) {
|
if (msgType === 0) {
|
||||||
// FramebufferUpdate
|
// FramebufferUpdate: type(1) + padding(1) + nRects(2). The type
|
||||||
|
// byte is already consumed above; hdr covers padding + nRects.
|
||||||
const hdr = drainTo(3);
|
const hdr = drainTo(3);
|
||||||
if (!hdr) { chunks.unshift(b); totalBytes += 1; return false; }
|
if (!hdr) { chunks.unshift(b); totalBytes += 1; return false; }
|
||||||
drainTo(1); // padding (already consumed with hdr? no — hdr is 3 bytes after the type)
|
|
||||||
// Actually: message type (1) + padding (1) + nRects (2) = 4 bytes total after type byte
|
|
||||||
// Let's re-do: type byte consumed, then 1 pad + 2 nRects = 3 bytes
|
|
||||||
updateRects = u16be(hdr, 1);
|
updateRects = u16be(hdr, 1);
|
||||||
state = 'rect-header';
|
state = 'rect-header';
|
||||||
} else if (msgType === 2) {
|
} else if (msgType === 2) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue