diff options
Diffstat (limited to 'common/rfb')
-rw-r--r-- | common/rfb/CConnection.cxx | 2 | ||||
-rw-r--r-- | common/rfb/CSecurityTLS.cxx | 19 | ||||
-rw-r--r-- | common/rfb/CSecurityTLS.h | 2 | ||||
-rw-r--r-- | common/rfb/ComparingUpdateTracker.cxx | 29 | ||||
-rw-r--r-- | common/rfb/ComparingUpdateTracker.h | 5 | ||||
-rw-r--r-- | common/rfb/Configuration.cxx | 19 | ||||
-rw-r--r-- | common/rfb/Configuration.h | 4 | ||||
-rw-r--r-- | common/rfb/HTTPServer.h | 12 | ||||
-rw-r--r-- | common/rfb/Hostname.h | 73 | ||||
-rw-r--r-- | common/rfb/KeyRemapper.cxx | 27 | ||||
-rw-r--r-- | common/rfb/KeyRemapper.h | 6 | ||||
-rw-r--r-- | common/rfb/Logger_file.cxx | 18 | ||||
-rw-r--r-- | common/rfb/Logger_file.h | 3 | ||||
-rw-r--r-- | common/rfb/Logger_syslog.cxx | 1 | ||||
-rw-r--r-- | common/rfb/SSecurityTLS.cxx | 20 | ||||
-rw-r--r-- | common/rfb/SSecurityTLS.h | 2 | ||||
-rw-r--r-- | common/rfb/Threading.h | 31 | ||||
-rw-r--r-- | common/rfb/VNCServerST.cxx | 9 | ||||
-rw-r--r-- | common/rfb/VNCServerST.h | 11 | ||||
-rw-r--r-- | common/rfb/ZRLEDecoder.cxx | 11 | ||||
-rw-r--r-- | common/rfb/hextileDecode.h | 6 | ||||
-rw-r--r-- | common/rfb/zrleDecode.h | 3 |
22 files changed, 173 insertions, 140 deletions
diff --git a/common/rfb/CConnection.cxx b/common/rfb/CConnection.cxx index 7e9fd310..35be9468 100644 --- a/common/rfb/CConnection.cxx +++ b/common/rfb/CConnection.cxx @@ -86,7 +86,7 @@ void CConnection::setFramebuffer(ModifiablePixelBuffer* fb) if (fb->width() > framebuffer->width()) { rect.setXYWH(framebuffer->width(), 0, - fb->width() - fb->width(), + fb->width() - framebuffer->width(), fb->height()); fb->fillRect(rect, black); } diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx index 3dcededb..8a053e3d 100644 --- a/common/rfb/CSecurityTLS.cxx +++ b/common/rfb/CSecurityTLS.cxx @@ -67,21 +67,14 @@ StringParameter CSecurityTLS::X509CRL("X509CRL", "X509 CRL file", "", ConfViewer static LogWriter vlog("TLS"); -void CSecurityTLS::initGlobal() -{ - static bool globalInitDone = false; - - if (!globalInitDone) { - gnutls_global_init(); - globalInitDone = true; - } -} - CSecurityTLS::CSecurityTLS(bool _anon) : session(0), anon_cred(0), anon(_anon), fis(0), fos(0) { cafile = X509CA.getData(); crlfile = X509CRL.getData(); + + if (gnutls_global_init() != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_global_init failed"); } void CSecurityTLS::setDefaults() @@ -125,8 +118,6 @@ void CSecurityTLS::shutdown(bool needbye) if (session) { gnutls_deinit(session); session = 0; - - gnutls_global_deinit(); } } @@ -142,6 +133,8 @@ CSecurityTLS::~CSecurityTLS() delete[] cafile; delete[] crlfile; + + gnutls_global_deinit(); } bool CSecurityTLS::processMsg(CConnection* cc) @@ -150,8 +143,6 @@ bool CSecurityTLS::processMsg(CConnection* cc) rdr::OutStream* os = cc->getOutStream(); client = cc; - initGlobal(); - if (!session) { if (!is->checkNoWait(1)) return false; diff --git a/common/rfb/CSecurityTLS.h b/common/rfb/CSecurityTLS.h index b147d802..57d964d7 100644 --- a/common/rfb/CSecurityTLS.h +++ b/common/rfb/CSecurityTLS.h @@ -62,8 +62,6 @@ namespace rfb { CConnection *client; private: - static void initGlobal(); - gnutls_session_t session; gnutls_anon_client_credentials_t anon_cred; gnutls_certificate_credentials_t cert_cred; diff --git a/common/rfb/ComparingUpdateTracker.cxx b/common/rfb/ComparingUpdateTracker.cxx index 1d27f3c4..237adc41 100644 --- a/common/rfb/ComparingUpdateTracker.cxx +++ b/common/rfb/ComparingUpdateTracker.cxx @@ -20,12 +20,16 @@ #include <vector> #include <rdr/types.h> #include <rfb/Exception.h> +#include <rfb/LogWriter.h> #include <rfb/ComparingUpdateTracker.h> using namespace rfb; +static LogWriter vlog("ComparingUpdateTracker"); + ComparingUpdateTracker::ComparingUpdateTracker(PixelBuffer* buffer) - : fb(buffer), oldFb(fb->getPF(), 0, 0), firstCompare(true), enabled(true) + : fb(buffer), oldFb(fb->getPF(), 0, 0), firstCompare(true), + enabled(true), totalPixels(0), missedPixels(0) { changed.assign_union(fb->getRect()); } @@ -72,6 +76,13 @@ bool ComparingUpdateTracker::compare() for (i = rects.begin(); i != rects.end(); i++) compareRect(*i, &newChanged); + changed.get_rects(&rects); + for (i = rects.begin(); i != rects.end(); i++) + totalPixels += i->area(); + newChanged.get_rects(&rects); + for (i = rects.begin(); i != rects.end(); i++) + missedPixels += i->area(); + if (changed.equals(newChanged)) return false; @@ -165,3 +176,19 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged) newChanged->assign_union(temp); } } + +void ComparingUpdateTracker::logStats() +{ + double ratio; + char a[1024], b[1024]; + + siPrefix(totalPixels, "pixels", a, sizeof(a)); + siPrefix(missedPixels, "pixels", b, sizeof(b)); + + ratio = (double)totalPixels / missedPixels; + + vlog.info("%s in / %s out", a, b); + vlog.info("(1:%g ratio)", ratio); + + totalPixels = missedPixels = 0; +} diff --git a/common/rfb/ComparingUpdateTracker.h b/common/rfb/ComparingUpdateTracker.h index fccc2222..e62f2b23 100644 --- a/common/rfb/ComparingUpdateTracker.h +++ b/common/rfb/ComparingUpdateTracker.h @@ -40,12 +40,17 @@ namespace rfb { virtual void enable(); virtual void disable(); + + void logStats(); + private: void compareRect(const Rect& r, Region* newchanged); PixelBuffer* fb; ManagedPixelBuffer oldFb; bool firstCompare; bool enabled; + + rdr::U32 totalPixels, missedPixels; }; } diff --git a/common/rfb/Configuration.cxx b/common/rfb/Configuration.cxx index 8e1ea6e9..a5c23028 100644 --- a/common/rfb/Configuration.cxx +++ b/common/rfb/Configuration.cxx @@ -23,24 +23,14 @@ #include <ctype.h> #include <string.h> +#include <os/Mutex.h> + #include <rfb/util.h> #include <rfb/Configuration.h> #include <rfb/LogWriter.h> #include <rfb/Exception.h> -#include <rfb/Threading.h> -#ifdef __RFB_THREADING_IMPL -// On platforms that support Threading, we use Locks to make getData safe -#define LOCK_CONFIG Lock l(*configLock()) -rfb::Mutex* configLock_ = 0; -static rfb::Mutex* configLock() { - if (!configLock_) - configLock_ = new rfb::Mutex; - return configLock_; -} -#else -#define LOCK_CONFIG -#endif +#define LOCK_CONFIG os::AutoMutex a(mutex) #include <rdr/HexOutStream.h> #include <rdr/HexInStream.h> @@ -195,9 +185,12 @@ VoidParameter::VoidParameter(const char* name_, const char* desc_, _next = conf->head; conf->head = this; + + mutex = new os::Mutex(); } VoidParameter::~VoidParameter() { + delete mutex; } const char* diff --git a/common/rfb/Configuration.h b/common/rfb/Configuration.h index da93fddf..fbf161db 100644 --- a/common/rfb/Configuration.h +++ b/common/rfb/Configuration.h @@ -45,6 +45,8 @@ #include <rfb/util.h> +namespace os { class Mutex; } + namespace rfb { class VoidParameter; struct ParameterIterator; @@ -174,6 +176,8 @@ namespace rfb { bool immutable; const char* name; const char* description; + + os::Mutex* mutex; }; class AliasParameter : public VoidParameter { diff --git a/common/rfb/HTTPServer.h b/common/rfb/HTTPServer.h index d7ca69ad..04ef4993 100644 --- a/common/rfb/HTTPServer.h +++ b/common/rfb/HTTPServer.h @@ -26,8 +26,6 @@ #ifndef __RFB_HTTP_SERVER_H__ #define __RFB_HTTP_SERVER_H__ -#include <list> - #include <rdr/MemInStream.h> #include <rfb/UpdateTracker.h> #include <rfb/Configuration.h> @@ -58,6 +56,10 @@ namespace rfb { // Could clean up socket-specific resources here. virtual void removeSocket(network::Socket* sock); + // getSockets() gets a list of sockets. This can be used to generate an + // fd_set for calling select(). + virtual void getSockets(std::list<network::Socket*>* sockets); + // processSocketReadEvent() // The platform-specific side of the server implementation calls // this method whenever data arrives on one of the active @@ -73,12 +75,6 @@ namespace rfb { virtual int checkTimeouts(); - // getSockets() gets a list of sockets. This can be used to generate an - // fd_set for calling select(). - - virtual void getSockets(std::list<network::Socket*>* sockets); - - // -=- File interface // - getFile is passed the path portion of a URL and returns an diff --git a/common/rfb/Hostname.h b/common/rfb/Hostname.h index f70347f9..bd68dc02 100644 --- a/common/rfb/Hostname.h +++ b/common/rfb/Hostname.h @@ -19,6 +19,7 @@ #ifndef __RFB_HOSTNAME_H__ #define __RFB_HOSTNAME_H__ +#include <assert.h> #include <stdlib.h> #include <rdr/Exception.h> #include <rfb/util.h> @@ -26,30 +27,72 @@ namespace rfb { static void getHostAndPort(const char* hi, char** host, int* port, int basePort=5900) { - CharArray portBuf; - CharArray hostBuf; + const char* hostStart; + const char* hostEnd; + const char* portStart; + if (hi == NULL) throw rdr::Exception("NULL host specified"); + + assert(host); + assert(port); + if (hi[0] == '[') { - if (!strSplit(&hi[1], ']', &hostBuf.buf, &portBuf.buf)) + hostStart = &hi[1]; + hostEnd = strchr(hostStart, ']'); + if (hostEnd == NULL) throw rdr::Exception("unmatched [ in host"); + + portStart = hostEnd + 1; + if (*portStart == '\0') + portStart = NULL; } else { - portBuf.buf = strDup(hi); - } - if (strSplit(portBuf.buf, ':', hostBuf.buf ? 0 : &hostBuf.buf, &portBuf.buf)) { - if (portBuf.buf[0] == ':') { - *port = atoi(&portBuf.buf[1]); + hostStart = &hi[0]; + hostEnd = strrchr(hostStart, ':'); + + if (hostEnd == NULL) { + hostEnd = hostStart + strlen(hostStart); + portStart = NULL; } else { - *port = atoi(portBuf.buf); - if (*port < 100) *port += basePort; + if ((hostEnd > hostStart) && (hostEnd[-1] == ':')) + hostEnd--; + portStart = strchr(hostStart, ':'); + if (portStart != hostEnd) { + // We found more : in the host. This is probably an IPv6 address + hostEnd = hostStart + strlen(hostStart); + portStart = NULL; + } } - } else { - *port = basePort; } - if (strlen(hostBuf.buf) == 0) + + if (hostStart == hostEnd) *host = strDup("localhost"); - else - *host = hostBuf.takeBuf(); + else { + size_t len; + len = hostEnd - hostStart + 1; + *host = new char[len]; + strncpy(*host, hostStart, len-1); + (*host)[len-1] = '\0'; + } + + if (portStart == NULL) + *port = basePort; + else { + char* end; + + if (portStart[0] != ':') + throw rdr::Exception("invalid port specified"); + + if (portStart[1] != ':') + *port = strtol(portStart + 1, &end, 10); + else + *port = strtol(portStart + 2, &end, 10); + if (*end != '\0') + throw rdr::Exception("invalid port specified"); + + if ((portStart[1] != ':') && (*port < 100)) + *port += basePort; + } } }; diff --git a/common/rfb/KeyRemapper.cxx b/common/rfb/KeyRemapper.cxx index d33f0a45..b4c2793c 100644 --- a/common/rfb/KeyRemapper.cxx +++ b/common/rfb/KeyRemapper.cxx @@ -17,6 +17,9 @@ */ #include <stdio.h> + +#include <os/Mutex.h> + #include <rfb/KeyRemapper.h> #include <rfb/Configuration.h> #include <rfb/LogWriter.h> @@ -27,14 +30,21 @@ static LogWriter vlog("KeyRemapper"); KeyRemapper KeyRemapper::defInstance; -#ifdef __RFB_THREADING_IMPL -static Mutex mappingLock; -#endif +KeyRemapper::KeyRemapper(const char* m) +{ + mutex = new os::Mutex; + + setMapping(m); +} + +KeyRemapper::~KeyRemapper() +{ + delete mutex; +} void KeyRemapper::setMapping(const char* m) { -#ifdef __RFB_THREADING_IMPL - Lock l(mappingLock); -#endif + os::AutoMutex a(mutex); + mapping.clear(); while (m[0]) { int from, to; @@ -59,9 +69,8 @@ void KeyRemapper::setMapping(const char* m) { } rdr::U32 KeyRemapper::remapKey(rdr::U32 key) const { -#ifdef __RFB_THREADING_IMPL - Lock l(mappingLock); -#endif + os::AutoMutex a(mutex); + std::map<rdr::U32,rdr::U32>::const_iterator i = mapping.find(key); if (i != mapping.end()) return i->second; diff --git a/common/rfb/KeyRemapper.h b/common/rfb/KeyRemapper.h index a4b7aa01..1406bad2 100644 --- a/common/rfb/KeyRemapper.h +++ b/common/rfb/KeyRemapper.h @@ -22,16 +22,20 @@ #include <map> #include <rdr/types.h> +namespace os { class Mutex; } + namespace rfb { class KeyRemapper { public: - KeyRemapper(const char* m="") { setMapping(m); } + KeyRemapper(const char* m=""); + ~KeyRemapper(); void setMapping(const char* m); rdr::U32 remapKey(rdr::U32 key) const; static KeyRemapper defInstance; private: std::map<rdr::U32,rdr::U32> mapping; + os::Mutex* mutex; }; }; diff --git a/common/rfb/Logger_file.cxx b/common/rfb/Logger_file.cxx index ebe15d52..149ad404 100644 --- a/common/rfb/Logger_file.cxx +++ b/common/rfb/Logger_file.cxx @@ -21,36 +21,30 @@ #include <stdlib.h> #include <string.h> +#include <os/Mutex.h> + #include <rfb/util.h> #include <rfb/Logger_file.h> -#include <rfb/Threading.h> using namespace rfb; - -// If threading is available then protect the write() operation -// from concurrent accesses -#ifdef __RFB_THREADING_IMPL -static Mutex logLock; -#endif - - Logger_File::Logger_File(const char* loggerName) : Logger(loggerName), indent(13), width(79), m_filename(0), m_file(0), m_lastLogTime(0) { + mutex = new os::Mutex(); } Logger_File::~Logger_File() { closeFile(); + delete mutex; } void Logger_File::write(int level, const char *logname, const char *message) { -#ifdef __RFB_THREADING_IMPL - Lock l(logLock); -#endif + os::AutoMutex a(mutex); + if (!m_file) { if (!m_filename) return; CharArray bakFilename(strlen(m_filename) + 1 + 4); diff --git a/common/rfb/Logger_file.h b/common/rfb/Logger_file.h index 5e0c917b..5b5c34e1 100644 --- a/common/rfb/Logger_file.h +++ b/common/rfb/Logger_file.h @@ -24,6 +24,8 @@ #include <time.h> #include <rfb/Logger.h> +namespace os { class Mutex; } + namespace rfb { class Logger_File : public Logger { @@ -43,6 +45,7 @@ namespace rfb { char* m_filename; FILE* m_file; time_t m_lastLogTime; + os::Mutex* mutex; }; bool initFileLogger(const char* filename); diff --git a/common/rfb/Logger_syslog.cxx b/common/rfb/Logger_syslog.cxx index 291d36cd..dc1d0c1a 100644 --- a/common/rfb/Logger_syslog.cxx +++ b/common/rfb/Logger_syslog.cxx @@ -25,7 +25,6 @@ #include <rfb/util.h> #include <rfb/Logger_syslog.h> #include <rfb/LogWriter.h> -#include <rfb/Threading.h> using namespace rfb; diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx index 0f52d34b..b9460223 100644 --- a/common/rfb/SSecurityTLS.cxx +++ b/common/rfb/SSecurityTLS.cxx @@ -48,23 +48,15 @@ StringParameter SSecurityTLS::X509_KeyFile static LogWriter vlog("TLS"); -void SSecurityTLS::initGlobal() -{ - static bool globalInitDone = false; - - if (!globalInitDone) { - if (gnutls_global_init() != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_global_init failed"); - globalInitDone = true; - } -} - SSecurityTLS::SSecurityTLS(bool _anon) : session(0), dh_params(0), anon_cred(0), cert_cred(0), anon(_anon), fis(0), fos(0) { certfile = X509_CertFile.getData(); keyfile = X509_KeyFile.getData(); + + if (gnutls_global_init() != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_global_init failed"); } void SSecurityTLS::shutdown() @@ -94,8 +86,6 @@ void SSecurityTLS::shutdown() if (session) { gnutls_deinit(session); session = 0; - - gnutls_global_deinit(); } } @@ -111,6 +101,8 @@ SSecurityTLS::~SSecurityTLS() delete[] keyfile; delete[] certfile; + + gnutls_global_deinit(); } bool SSecurityTLS::processMsg(SConnection *sc) @@ -121,8 +113,6 @@ bool SSecurityTLS::processMsg(SConnection *sc) vlog.debug("Process security message (session %p)", session); if (!session) { - initGlobal(); - if (gnutls_init(&session, GNUTLS_SERVER) != GNUTLS_E_SUCCESS) throw AuthFailureException("gnutls_init failed"); diff --git a/common/rfb/SSecurityTLS.h b/common/rfb/SSecurityTLS.h index a7932054..30242a24 100644 --- a/common/rfb/SSecurityTLS.h +++ b/common/rfb/SSecurityTLS.h @@ -54,8 +54,6 @@ namespace rfb { void setParams(gnutls_session_t session); private: - static void initGlobal(); - gnutls_session_t session; gnutls_dh_params_t dh_params; gnutls_anon_server_credentials_t anon_cred; diff --git a/common/rfb/Threading.h b/common/rfb/Threading.h deleted file mode 100644 index 66b3aa0f..00000000 --- a/common/rfb/Threading.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- Threading.h -// General purpose threading interface. -// If the current platform supports threading then __RFB_THREADING_IMPL -// will be defined after this header has been included. - -#ifndef __RFB_THREADING_H__ -#define __RFB_THREADING_H__ - -#ifdef WIN32 -#include <rfb_win32/Threading.h> -#endif - -#endif // __RFB_THREADING_H__ diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index d5010854..e15cd701 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -110,6 +110,8 @@ VNCServerST::~VNCServerST() desktop->stop(); } + if (comparer) + comparer->logStats(); delete comparer; } @@ -155,6 +157,10 @@ void VNCServerST::removeSocket(network::Socket* sock) { desktopStarted = false; desktop->stop(); } + + if (comparer) + comparer->logStats(); + return; } } @@ -292,6 +298,9 @@ void VNCServerST::unblockUpdates() void VNCServerST::setPixelBuffer(PixelBuffer* pb_, const ScreenSet& layout) { + if (comparer) + comparer->logStats(); + pb = pb_; delete comparer; comparer = 0; diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index bd84c452..0ced12a4 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -25,8 +25,6 @@ #include <sys/time.h> -#include <list> - #include <rfb/SDesktop.h> #include <rfb/VNCServer.h> #include <rfb/Configuration.h> @@ -67,6 +65,10 @@ namespace rfb { // Clean up any resources associated with the Socket virtual void removeSocket(network::Socket* sock); + // getSockets() gets a list of sockets. This can be used to generate an + // fd_set for calling select(). + virtual void getSockets(std::list<network::Socket*>* sockets); + // processSocketReadEvent // Read more RFB data from the Socket. If an error occurs during // processing then shutdown() is called on the Socket, causing @@ -111,11 +113,6 @@ namespace rfb { // any), and logs the specified reason for closure. void closeClients(const char* reason, network::Socket* sock); - // getSockets() gets a list of sockets. This can be used to generate an - // fd_set for calling select(). - - void getSockets(std::list<network::Socket*>* sockets); - // getSConnection() gets the SConnection for a particular Socket. If // the Socket is not recognised then null is returned. diff --git a/common/rfb/ZRLEDecoder.cxx b/common/rfb/ZRLEDecoder.cxx index c13f2861..b891ba52 100644 --- a/common/rfb/ZRLEDecoder.cxx +++ b/common/rfb/ZRLEDecoder.cxx @@ -86,10 +86,9 @@ void ZRLEDecoder::decodeRect(const Rect& r, const void* buffer, { rdr::MemInStream is(buffer, buflen); const rfb::PixelFormat& pf = cp.pf(); - rdr::U8* buf[64 * 64 * 4 * pf.bpp/8]; switch (pf.bpp) { - case 8: zrleDecode8 (r, &is, &zis, (rdr::U8*) buf, pf, pb); break; - case 16: zrleDecode16(r, &is, &zis, (rdr::U16*)buf, pf, pb); break; + case 8: zrleDecode8 (r, &is, &zis, pf, pb); break; + case 16: zrleDecode16(r, &is, &zis, pf, pb); break; case 32: { Pixel maxPixel = pf.pixelFromRGB((rdr::U16)-1, (rdr::U16)-1, (rdr::U16)-1); @@ -99,16 +98,16 @@ void ZRLEDecoder::decodeRect(const Rect& r, const void* buffer, if ((fitsInLS3Bytes && pf.isLittleEndian()) || (fitsInMS3Bytes && pf.isBigEndian())) { - zrleDecode24A(r, &is, &zis, (rdr::U32*)buf, pf, pb); + zrleDecode24A(r, &is, &zis, pf, pb); } else if ((fitsInLS3Bytes && pf.isBigEndian()) || (fitsInMS3Bytes && pf.isLittleEndian())) { - zrleDecode24B(r, &is, &zis, (rdr::U32*)buf, pf, pb); + zrleDecode24B(r, &is, &zis, pf, pb); } else { - zrleDecode32(r, &is, &zis, (rdr::U32*)buf, pf, pb); + zrleDecode32(r, &is, &zis, pf, pb); } break; } diff --git a/common/rfb/hextileDecode.h b/common/rfb/hextileDecode.h index 7affa157..402cd031 100644 --- a/common/rfb/hextileDecode.h +++ b/common/rfb/hextileDecode.h @@ -22,6 +22,7 @@ // BPP - 8, 16 or 32 #include <rdr/InStream.h> +#include <rfb/Exception.h> #include <rfb/hextileConstants.h> namespace rfb { @@ -44,7 +45,7 @@ static void HEXTILE_DECODE (const Rect& r, rdr::InStream* is, Rect t; PIXEL_T bg = 0; PIXEL_T fg = 0; - PIXEL_T buf[16 * 16 * 4]; + PIXEL_T buf[16 * 16]; for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 16) { @@ -87,6 +88,9 @@ static void HEXTILE_DECODE (const Rect& r, rdr::InStream* is, int y = (xy & 15); int w = ((wh >> 4) & 15) + 1; int h = (wh & 15) + 1; + if (x + w > 16 || y + h > 16) { + throw rfb::Exception("HEXTILE_DECODE: Hextile out of bounds"); + } PIXEL_T* ptr = buf + y * t.width() + x; int rowAdd = t.width() - w; while (h-- > 0) { diff --git a/common/rfb/zrleDecode.h b/common/rfb/zrleDecode.h index 07d6795a..0bfbbe15 100644 --- a/common/rfb/zrleDecode.h +++ b/common/rfb/zrleDecode.h @@ -47,12 +47,13 @@ namespace rfb { #endif void ZRLE_DECODE (const Rect& r, rdr::InStream* is, - rdr::ZlibInStream* zis, PIXEL_T* buf, + rdr::ZlibInStream* zis, const PixelFormat& pf, ModifiablePixelBuffer* pb) { int length = is->readU32(); zis->setUnderlying(is, length); Rect t; + PIXEL_T buf[64 * 64]; for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 64) { |