Luke Shumaker [Tue, 23 May 2017 18:03:15 +0000 (14:03 -0400)]
vncviewer: Fix scrollbar visibility
Have a window that is sized to the remote screen. Now shrink the window
vertically, making it shorter than the remote screen in one axis. The
vertical scrollbar appears. However, the horizontal scrollbar does not
appear, despite the rightmost ~24 pixels (Fl::scrollbar_size()) being
hidden by the vertical scroll bar.
Fix that.
For clarity, move the fullscreen checks into a separate `if` statement,
rather than keeping the size and fullscreen checks together.
I think the comment does a decent job of explaining and justifying the
check's logic, but if you require further convincing, perhaps this
alternate explanation will help:
To be a bit more verbose and repetitive, we can split that ternary in to
two separate checks, and add some comments:
if (
(w() - < viewport->w()) // X needs a scrollbar
||
( (w() - Fl::scrollbar_size() < viewport->w()) && (h() < viewport->h()) )
//( X doesn't need a scrollbar unless Y does ) && ( Y does need one ) )
)
Within the "Y does need one" check, we don't need to worry about the
case where `h() - Fl::scrollbar_size() < viewport-h()` is true,
because if both axes are saying "I don't need a scrollbar unless
you do", then neither needs one.
Pierre Ossman [Fri, 28 Apr 2017 09:40:02 +0000 (11:40 +0200)]
Filter out alpha channel for normal draw() operation
macOS actually uses the alpha channel on windows, so we can get visual
artifacts if we feed it bogus alpha data. This filtering unfortunately
causes some CPU usage, but it's necessary until we can make sure the
framebuffer always contains proper 0xff for alpha.
Pierre Ossman [Fri, 28 Apr 2017 09:37:12 +0000 (11:37 +0200)]
Use correct color space for current monitor
We won't always be on the primary monitor, so check which color space
we're actually using right now. For offscreen stuff we assume a standard
sRGB color space.
Pierre Ossman [Fri, 28 Apr 2017 09:33:28 +0000 (11:33 +0200)]
Create new CGImage for each draw
The system expects these to be immutable, so changing the data after
creation only works in some special cases. We need to recreate the
CGImage object each time we've changed something.
Michal Srb [Thu, 6 Apr 2017 20:52:22 +0000 (23:52 +0300)]
Limit size of cursor accepted by client.
Width and height of a cursor are received as U16 from network. Accepting full range of U16 values can cause integer overflows in multiple places.
The worst is probably VLA in CMsgReader::readSetXCursor:
rdr::U8 buf[width*height*4];
The width*height*4 can be too big to fit on stack or it can overflow into negative numbers. Both cases are undefined behaviour. Following writes to buf can overwrite other data on stack.
Michal Srb [Wed, 29 Mar 2017 14:05:45 +0000 (17:05 +0300)]
Limit max username/password size in SSecurityPlain.
Setting the limit to 1024 which should be still more than enough.
Unlimited ulen and plen can cause various security problems:
* Overflow in `is->checkNoWait(ulen + plen)` causing it to contine when there is not enough data and then wait forever.
* Overflow in `new char[plen + 1]` that would allocate zero sized array which succeeds but returns pointer that should not be written into.
* Allocation failure in `new char[plen + 1]` from trying to allocate too much and crashing the whole server.
All those issues can be triggered by a client before authentication.
Michal Srb [Wed, 29 Mar 2017 14:00:30 +0000 (17:00 +0300)]
Fix checkNoWait logic in SSecurityPlain.
Currently it proceeds only if there aren't enough data in queue and then it blocks waiting.
Also the required amount to receive from network is (ulen + plen), not (ulen + plen + 2).
This allowed not authenticated clients to deny service to everyone.
Michal Srb [Mon, 27 Mar 2017 16:02:15 +0000 (19:02 +0300)]
Prevent double free by crafted fences.
If client sent fence with some data, followed by fence with no data (length 0), the original fence data were freed, but the pointer kept pointing at them. Sending one more fence would attempt to free them again.
Michal Srb [Mon, 27 Mar 2017 10:37:11 +0000 (13:37 +0300)]
Fix crash from integer overflow in SMsgReader::readClientCutText
The length sent by client is U32, but is converted into int. If it was bigger than 0x7fffffff the resulting int is negative, it passes the check against maxCutText and later throws std::bad_alloc from CharArray which takes down the whole server.
All the Streaming API deals with lengths in ints, so we can't tell it to skip that big amount of data. And it is not realistic to expect more than 2GB of clipboard data anyway. So lets just throw rdr::Exception that will disconnect this client and keep the server alive.
Pierre Ossman [Fri, 7 Oct 2016 13:59:38 +0000 (15:59 +0200)]
Send updates with a fixed interval
This redesigns the old "deferred updates" mechanism in to a frame
clock that governs how often updates are sent out. The goal is still
the same, to aggregate updates and avoid pointless updates, all in
the name of efficiency. This model should however be more robust
against delays that sometimes causes us to miss the desired rate.
Pierre Ossman [Fri, 24 Feb 2017 11:33:09 +0000 (12:33 +0100)]
Display performance statistics in viewer
Adds an optional graph to the viewer to display current frame rate,
pixel rate and network bandwidth. Makes it easier to debug and test
performance related issues.
Pierre Ossman [Mon, 13 Feb 2017 12:47:37 +0000 (13:47 +0100)]
Fix wrapping/unwrapping of X11 hooks
The functions might change so we need to also make sure we grab
the updated value after each call. Clean up the code to use the
same style as the rest of the Xorg code.
Brian P. Hinz [Fri, 10 Feb 2017 04:41:56 +0000 (23:41 -0500)]
Fix regression that omitted support for client redirect.
Also, delay showing DesktopWindow until first valid rect has been
recieved. This allows for a ClientRedirect to take place before
any data rects have been received.
Pierre Ossman [Mon, 2 Jan 2017 18:49:52 +0000 (19:49 +0100)]
Render on a temporary surface when needed
Some platforms draw directly to the screen, which means that updates
will flicker if we draw multiple layers. Prevent this by first
composing the update on a hidden surface.