Skip to content

Conversation

@codewithnithish
Copy link

No description provided.

1) Added support for non-standard server version `003.005` by mapping it to RFB 3.3 in the protocol negotiation switch. File: `core/rfb.js`.
2) Added a warning log when `003.005` is seen so it is clear we are forcing a 3.3 handshake. File: `core/rfb.js`.
3) Stored the server pixel format from ServerInit, and passed it through to decoders so we can decode non-24bpp pixel data safely. File: `core/rfb.js`.
4) Added a compatibility path to force 16bpp and restrict encodings to raw when the server reports non-standard 3.4/3.5. File: `core/rfb.js`.
5) Added 16bpp RAW decoding with proper bit-mask conversion to RGBA (handles 5-5-5 and 5-6-5 formats). File: `core/decoders/raw.js`.
Support_for_non-standard_server_version
Modified decodeRect to handle 16bpp raw pixel format decoding with customizable parameters.
@codewithnithish codewithnithish changed the title Codewithnithish feature support for non standard vnc server version Support for non-standard server version 003.005 Jan 8, 2026
@samhed
Copy link
Member

samhed commented Jan 11, 2026

We're going to need some background here. Where is this version used?

@codewithnithish
Copy link
Author

We're going to need some background here. Where is this version used?

@sambhed Thanks for the quick review and for asking for context — happy to provide it!

Why this PR is needed

noVNC currently rejects connections from servers advertising non-standard RFB protocol versions outside the official range (mainly 003.003 to 003.008, plus a few others like 004.* / 005.*).
The version "003.005" is not part of the official RFB specification, but it does appear in production on certain legacy embedded/industrial devices.

The problem this solves

Users trying to access these legacy devices via a modern web browser (using noVNC) get immediately disconnected with an error like:
Invalid server version '003.005'

This forces them to:

  • Use outdated/native VNC clients (often Windows-only, insecure, or hard to deploy remotely)
  • Avoid web-based remote access entirely
  • Resort to workarounds that break browser compatibility

By allowing negotiation to continue (while falling back to safe/compatible behavior similar to 003.003), this PR enables browser-based access to these devices without any negative impact on standard VNC servers.

The change is very targeted/minimal — it just adds one more accepted version string during handshake, with no protocol behavior changes.

Happy to answer any questions, or refine the implementation (e.g., add a log warning for non-standard versions, make it configurable, etc.).

Thanks again for considering this — it would help a niche but real user base with aging hardware!

@CendioOssman
Copy link
Member

The specification is clear that version 3.5 should be treated as version 3.3. So that's an obvious fix.

The controversial part is the rest of the changes. I.e. the workarounds for a buggy server that doesn't correctly respect the client pixel format. Assuming it is such a buggy server, just based on the version number seems very fragile.

This use case is something that keeps popping up, and we rarely have the ability to automatically detect these broken servers. Although I loathe adding settings needlessly, perhaps this is a case where there simply isn't any other way (besides simply stating we refuse to support buggy servers).

@codewithnithish
Copy link
Author

Thanks for the detailed feedback — really appreciate the insight into the spec and the hesitation around fragility.

You're absolutely right: per RFC 6143 and the original RFB docs, any non-3.7/3.8 version (including buggy/misreported 3.5) must be treated as 3.3 during negotiation. So adding explicit support for "003.005" → fallback to 3.3 is a no-brainer and low-risk. I can separate that into a tiny standalone commit/PR if it helps keep things clean.

The more controversial part is indeed the workaround for the buggy pixel format handling on these specific legacy servers (LS Industrial eXP60 series and similar embedded HMIs). From user reports and packet captures shared in various support threads, these devices:

  • Advertise 003.005
  • Ignore the client's SetPixelFormat request (or mishandle it)
  • Send framebuffer updates using a fixed 16bpp format (often 5-6-5 RGB565 or similar), regardless of what the client asked for

This leads to garbled/corrupted display in noVNC unless we force a compatible client-side format (16bpp) and restrict encodings to raw (since other encodings assume the negotiated format is respected).

Addressing fragility

I agree — keying off the version string alone is brittle if other servers ever start using 003.005 legitimately (unlikely, but possible).
Better alternatives I've considered (and happy to implement one):

  1. Make the workaround optional via a URL parameter (e.g., ?forceLegacyHMI=true or ?compat=ls-industrial-003.005)

    • This avoids global assumptions
    • Only enables the 16bpp/raw forcing when explicitly requested
    • Users with these devices can just add the param to their connection URL
    • Zero impact on everyone else
  2. Detect the bug dynamically (harder, but more robust):

    • After SetPixelFormat, send a small test framebuffer update request
    • If the server sends data in a clearly mismatched format (e.g., 16bpp when we requested 32bpp), trigger compatibility mode
    • This would be automatic but adds some complexity/handshake overhead
  3. Strict refusal (documented policy):

    • We could just reject 003.005 entirely and note in docs that certain legacy industrial devices are unsupported due to protocol violations
    • This is cleanest for the codebase but leaves users stuck with native clients

Since this issue has come up repeatedly for industrial/retail users with long-lifecycle hardware, I think option 1 (explicit opt-in flag) strikes the best balance: it supports the real use case without polluting the default path or assuming too much based on version alone.

Would you prefer:

  • Splitting the PR: one for the version 3.5→3.3 mapping (mergeable now)
  • Then a follow-up for the opt-in compatibility mode?
  • Or keep it together with the flag from the start?

Happy to adjust the code accordingly (e.g., add the URL param, log clearly when activated, etc.). Thanks again for the thoughtful review — this kind of discussion is what makes noVNC reliable!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants