Browse Source

Return std::string instead of dynamic allocations

We mostly use classical C strings, but the memory management around them
can get confusing and error prone. Let's use std::string for the cases
where we need to return a newly allocated string.
pull/1587/head
Pierre Ossman 1 year ago
parent
commit
337dbc3922
47 changed files with 357 additions and 450 deletions
  1. 14
    7
      common/network/TcpSocket.cxx
  2. 3
    2
      common/network/TcpSocket.h
  3. 8
    7
      common/rfb/CConnection.cxx
  4. 1
    4
      common/rfb/CMsgHandler.cxx
  5. 2
    2
      common/rfb/CMsgReader.cxx
  6. 8
    9
      common/rfb/CSecurityDH.cxx
  7. 8
    9
      common/rfb/CSecurityMSLogonII.cxx
  8. 7
    8
      common/rfb/CSecurityPlain.cxx
  9. 15
    18
      common/rfb/CSecurityRSAAES.cxx
  10. 4
    6
      common/rfb/CSecurityVncAuth.cxx
  11. 3
    5
      common/rfb/ComparingUpdateTracker.cxx
  12. 21
    25
      common/rfb/Configuration.cxx
  13. 12
    16
      common/rfb/Configuration.h
  14. 9
    12
      common/rfb/DecodeManager.cxx
  15. 13
    17
      common/rfb/EncodeManager.cxx
  16. 6
    9
      common/rfb/Hostname.h
  17. 1
    1
      common/rfb/LogWriter.cxx
  18. 8
    7
      common/rfb/SConnection.cxx
  19. 1
    4
      common/rfb/SMsgHandler.cxx
  20. 2
    2
      common/rfb/SMsgReader.cxx
  21. 2
    1
      common/rfb/SSecurityPlain.cxx
  22. 7
    3
      common/rfb/UserPasswdGetter.h
  23. 74
    102
      common/rfb/util.cxx
  24. 13
    14
      common/rfb/util.h
  25. 3
    6
      tests/perf/fbperf.cxx
  26. 6
    10
      tests/unit/convertlf.cxx
  27. 3
    5
      tests/unit/hostport.cxx
  28. 6
    10
      tests/unit/unicode.cxx
  29. 5
    15
      unix/xserver/hw/vnc/RFBGlue.cc
  30. 2
    3
      unix/xserver/hw/vnc/vncExtInit.cc
  31. 8
    9
      vncviewer/CConn.cxx
  32. 1
    1
      vncviewer/CConn.h
  33. 4
    6
      vncviewer/DesktopWindow.cxx
  34. 8
    8
      vncviewer/UserDialog.cxx
  35. 2
    1
      vncviewer/UserDialog.h
  36. 3
    5
      vncviewer/Viewport.cxx
  37. 8
    12
      win/rfb_win32/Clipboard.cxx
  38. 1
    1
      win/rfb_win32/Clipboard.h
  39. 2
    3
      win/rfb_win32/RegConfig.cxx
  40. 22
    31
      win/rfb_win32/Registry.cxx
  41. 3
    3
      win/rfb_win32/Registry.h
  42. 1
    2
      win/rfb_win32/SDisplay.cxx
  43. 3
    3
      win/rfb_win32/Win32Util.cxx
  44. 2
    2
      win/vncconfig/Authentication.h
  45. 10
    10
      win/vncconfig/Connections.h
  46. 3
    4
      win/vncconfig/Legacy.cxx
  47. 9
    10
      win/winvnc/VNCServerWin32.cxx

+ 14
- 7
common/network/TcpSocket.cxx View File

return new TcpSocket(fd); return new TcpSocket(fd);
} }


void TcpListener::getMyAddresses(std::list<char*>* result) {
std::list<std::string> TcpListener::getMyAddresses() {
struct addrinfo *ai, *current, hints; struct addrinfo *ai, *current, hints;
std::list<std::string> result;


initSockets(); initSockets();




// Windows doesn't like NULL for service, so specify something // Windows doesn't like NULL for service, so specify something
if ((getaddrinfo(NULL, "1", &hints, &ai)) != 0) if ((getaddrinfo(NULL, "1", &hints, &ai)) != 0)
return;
return result;


for (current= ai; current != NULL; current = current->ai_next) { for (current= ai; current != NULL; current = current->ai_next) {
char addr[INET6_ADDRSTRLEN];

switch (current->ai_family) { switch (current->ai_family) {
case AF_INET: case AF_INET:
if (!UseIPv4) if (!UseIPv4)
continue; continue;
} }


char *addr = new char[INET6_ADDRSTRLEN];

getnameinfo(current->ai_addr, current->ai_addrlen, addr, INET6_ADDRSTRLEN, getnameinfo(current->ai_addr, current->ai_addrlen, addr, INET6_ADDRSTRLEN,
NULL, 0, NI_NUMERICHOST); NULL, 0, NI_NUMERICHOST);


result->push_back(addr);
result.push_back(addr);
} }


freeaddrinfo(ai); freeaddrinfo(ai);

return result;
} }


int TcpListener::getMyPort() { int TcpListener::getMyPort() {
return pattern; return pattern;
} }


char* TcpFilter::patternToStr(const TcpFilter::Pattern& p) {
std::string TcpFilter::patternToStr(const TcpFilter::Pattern& p) {
char addr[INET6_ADDRSTRLEN + 2]; char addr[INET6_ADDRSTRLEN + 2];


if (p.address.u.sa.sa_family == AF_INET) { if (p.address.u.sa.sa_family == AF_INET) {
else else
snprintf(result, resultlen, "%c%s/%u", action, addr, p.prefixlen); snprintf(result, resultlen, "%c%s/%u", action, addr, p.prefixlen);


return result;
std::string out = result;

delete [] result;

return out;
} }

+ 3
- 2
common/network/TcpSocket.h View File

#endif #endif


#include <list> #include <list>
#include <string>


/* Tunnelling support. */ /* Tunnelling support. */
#define TUNNEL_PORT_OFFSET 5500 #define TUNNEL_PORT_OFFSET 5500


virtual int getMyPort(); virtual int getMyPort();


static void getMyAddresses(std::list<char*>* result);
static std::list<std::string> getMyAddresses();


protected: protected:
virtual Socket* createSocket(int fd); virtual Socket* createSocket(int fd);
vnc_sockaddr_t mask; // computed from address and prefix vnc_sockaddr_t mask; // computed from address and prefix
}; };
static Pattern parsePattern(const char* s); static Pattern parsePattern(const char* s);
static char* patternToStr(const Pattern& p);
static std::string patternToStr(const Pattern& p);
protected: protected:
std::list<Pattern> filter; std::list<Pattern> filter;
}; };

+ 8
- 7
common/rfb/CConnection.cxx View File

strFree(serverClipboard); strFree(serverClipboard);
serverClipboard = NULL; serverClipboard = NULL;


serverClipboard = latin1ToUTF8(str);
serverClipboard = strDup(latin1ToUTF8(str).c_str());


handleClipboardAnnounce(true); handleClipboardAnnounce(true);
} }
strFree(serverClipboard); strFree(serverClipboard);
serverClipboard = NULL; serverClipboard = NULL;


serverClipboard = convertLF((const char*)data[0], lengths[0]);
std::string filtered(convertLF((const char*)data[0], lengths[0]));
serverClipboard = strDup(filtered.c_str());


// FIXME: Should probably verify that this data was actually requested // FIXME: Should probably verify that this data was actually requested
handleClipboardData(serverClipboard); handleClipboardData(serverClipboard);
void CConnection::sendClipboardData(const char* data) void CConnection::sendClipboardData(const char* data)
{ {
if (server.clipboardFlags() & rfb::clipboardProvide) { if (server.clipboardFlags() & rfb::clipboardProvide) {
CharArray filtered(convertCRLF(data));
size_t sizes[1] = { strlen(filtered.buf) + 1 };
const uint8_t* data[1] = { (const uint8_t*)filtered.buf };
std::string filtered(convertCRLF(data));
size_t sizes[1] = { filtered.size() + 1 };
const uint8_t* data[1] = { (const uint8_t*)filtered.c_str() };


if (unsolicitedClipboardAttempt) { if (unsolicitedClipboardAttempt) {
unsolicitedClipboardAttempt = false; unsolicitedClipboardAttempt = false;


writer()->writeClipboardProvide(rfb::clipboardUTF8, sizes, data); writer()->writeClipboardProvide(rfb::clipboardUTF8, sizes, data);
} else { } else {
CharArray latin1(utf8ToLatin1(data));
std::string latin1(utf8ToLatin1(data));


writer()->writeClientCutText(latin1.buf);
writer()->writeClientCutText(latin1.c_str());
} }
} }



+ 1
- 4
common/rfb/CMsgHandler.cxx View File

if (lengths[i] == 0) if (lengths[i] == 0)
vlog.debug(" %s (only notify)", type); vlog.debug(" %s (only notify)", type);
else { else {
char bytes[1024];

iecPrefix(lengths[i], "B", bytes, sizeof(bytes));
vlog.debug(" %s (automatically send up to %s)", vlog.debug(" %s (automatically send up to %s)",
type, bytes);
type, iecPrefix(lengths[i], "B").c_str());
} }
} }
} }

+ 2
- 2
common/rfb/CMsgReader.cxx View File

} }
CharArray ca(len); CharArray ca(len);
is->readBytes(ca.buf, len); is->readBytes(ca.buf, len);
CharArray filtered(convertLF(ca.buf, len));
handler->serverCutText(filtered.buf);
std::string filtered(convertLF(ca.buf, len));
handler->serverCutText(filtered.c_str());


return true; return true;
} }

+ 8
- 9
common/rfb/CSecurityDH.cxx View File



void CSecurityDH::writeCredentials() void CSecurityDH::writeCredentials()
{ {
CharArray username;
CharArray password;
std::string username;
std::string password;
rdr::RandomStream rs; rdr::RandomStream rs;


(CSecurity::upg)->getUserPasswd(isSecure(), &username.buf, &password.buf);
(CSecurity::upg)->getUserPasswd(isSecure(), &username, &password);

std::vector<uint8_t> bBytes(keyLength); std::vector<uint8_t> bBytes(keyLength);
if (!rs.hasData(keyLength)) if (!rs.hasData(keyLength))
throw ConnFailedException("failed to generate DH private key"); throw ConnFailedException("failed to generate DH private key");
if (!rs.hasData(128)) if (!rs.hasData(128))
throw ConnFailedException("failed to generate random padding"); throw ConnFailedException("failed to generate random padding");
rs.readBytes(buf, 128); rs.readBytes(buf, 128);
size_t len = strlen(username.buf);
if (len >= 64)
if (username.size() >= 64)
throw AuthFailureException("username is too long"); throw AuthFailureException("username is too long");
memcpy(buf, username.buf, len + 1);
len = strlen(password.buf);
if (len >= 64)
memcpy(buf, username.c_str(), username.size() + 1);
if (password.size() >= 64)
throw AuthFailureException("password is too long"); throw AuthFailureException("password is too long");
memcpy(buf + 64, password.buf, len + 1);
memcpy(buf + 64, password.c_str(), password.size() + 1);
aes128_encrypt(&aesCtx, 128, (uint8_t *)buf, (uint8_t *)buf); aes128_encrypt(&aesCtx, 128, (uint8_t *)buf, (uint8_t *)buf);


rdr::OutStream* os = cc->getOutStream(); rdr::OutStream* os = cc->getOutStream();

+ 8
- 9
common/rfb/CSecurityMSLogonII.cxx View File



void CSecurityMSLogonII::writeCredentials() void CSecurityMSLogonII::writeCredentials()
{ {
CharArray username;
CharArray password;
std::string username;
std::string password;
rdr::RandomStream rs; rdr::RandomStream rs;


(CSecurity::upg)->getUserPasswd(isSecure(), &username.buf, &password.buf);
(CSecurity::upg)->getUserPasswd(isSecure(), &username, &password);

std::vector<uint8_t> bBytes(8); std::vector<uint8_t> bBytes(8);
if (!rs.hasData(8)) if (!rs.hasData(8))
throw ConnFailedException("failed to generate DH private key"); throw ConnFailedException("failed to generate DH private key");
throw ConnFailedException("failed to generate random padding"); throw ConnFailedException("failed to generate random padding");
rs.readBytes(user, 256); rs.readBytes(user, 256);
rs.readBytes(pass, 64); rs.readBytes(pass, 64);
size_t len = strlen(username.buf);
if (len >= 256)
if (username.size() >= 256)
throw AuthFailureException("username is too long"); throw AuthFailureException("username is too long");
memcpy(user, username.buf, len + 1);
len = strlen(password.buf);
if (len >= 64)
memcpy(user, username.c_str(), username.size() + 1);
if (password.size() >= 64)
throw AuthFailureException("password is too long"); throw AuthFailureException("password is too long");
memcpy(pass, password.buf, len + 1);
memcpy(pass, password.c_str(), password.size() + 1);


// DES-CBC with the original key as IV, and the reversed one as the DES key // DES-CBC with the original key as IV, and the reversed one as the DES key
struct CBC_CTX(struct des_ctx, DES_BLOCK_SIZE) ctx; struct CBC_CTX(struct des_ctx, DES_BLOCK_SIZE) ctx;

+ 7
- 8
common/rfb/CSecurityPlain.cxx View File

#include <rfb/CConnection.h> #include <rfb/CConnection.h>
#include <rfb/CSecurityPlain.h> #include <rfb/CSecurityPlain.h>
#include <rfb/UserPasswdGetter.h> #include <rfb/UserPasswdGetter.h>
#include <rfb/util.h>


#include <rdr/OutStream.h> #include <rdr/OutStream.h>


{ {
rdr::OutStream* os = cc->getOutStream(); rdr::OutStream* os = cc->getOutStream();


CharArray username;
CharArray password;
std::string username;
std::string password;


(CSecurity::upg)->getUserPasswd(cc->isSecure(), &username.buf, &password.buf);
(CSecurity::upg)->getUserPasswd(cc->isSecure(), &username, &password);


// Return the response to the server // Return the response to the server
os->writeU32(strlen(username.buf));
os->writeU32(strlen(password.buf));
os->writeBytes(username.buf,strlen(username.buf));
os->writeBytes(password.buf,strlen(password.buf));
os->writeU32(username.size());
os->writeU32(password.size());
os->writeBytes(username.data(), username.size());
os->writeBytes(password.data(), password.size());
os->flush(); os->flush();
return true; return true;
} }

+ 15
- 18
common/rfb/CSecurityRSAAES.cxx View File



void CSecurityRSAAES::writeCredentials() void CSecurityRSAAES::writeCredentials()
{ {
CharArray username;
CharArray password;
std::string username;
std::string password;


(CSecurity::upg)->getUserPasswd(
isSecure(),
subtype == secTypeRA2UserPass ? &username.buf : NULL, &password.buf
);
size_t len;
if (username.buf) {
len = strlen(username.buf);
if (len > 255)
if (subtype == secTypeRA2UserPass)
(CSecurity::upg)->getUserPasswd(isSecure(), &username, &password);
else
(CSecurity::upg)->getUserPasswd(isSecure(), NULL, &password);

if (subtype == secTypeRA2UserPass) {
if (username.size() > 255)
throw AuthFailureException("username is too long"); throw AuthFailureException("username is too long");
raos->writeU8(len);
if (len)
raos->writeBytes(username.buf, len);
raos->writeU8(username.size());
raos->writeBytes(username.data(), username.size());
} else { } else {
raos->writeU8(0); raos->writeU8(0);
} }
len = strlen(password.buf);
if (len > 255)
if (password.size() > 255)
throw AuthFailureException("password is too long"); throw AuthFailureException("password is too long");
raos->writeU8(len);
if (len)
raos->writeBytes(password.buf, len);
raos->writeU8(password.size());
raos->writeBytes(password.data(), password.size());
raos->flush(); raos->flush();
} }

+ 4
- 6
common/rfb/CSecurityVncAuth.cxx View File

#include <stdio.h> #include <stdio.h>


#include <rfb/CConnection.h> #include <rfb/CConnection.h>
#include <rfb/Password.h>
#include <rfb/CSecurityVncAuth.h> #include <rfb/CSecurityVncAuth.h>
#include <rfb/util.h> #include <rfb/util.h>
#include <rfb/Security.h> #include <rfb/Security.h>
// Read the challenge & obtain the user's password // Read the challenge & obtain the user's password
uint8_t challenge[vncAuthChallengeSize]; uint8_t challenge[vncAuthChallengeSize];
is->readBytes(challenge, vncAuthChallengeSize); is->readBytes(challenge, vncAuthChallengeSize);
PlainPasswd passwd;
(CSecurity::upg)->getUserPasswd(cc->isSecure(), 0, &passwd.buf);
std::string passwd;
(CSecurity::upg)->getUserPasswd(cc->isSecure(), 0, &passwd);


// Calculate the correct response // Calculate the correct response
uint8_t key[8]; uint8_t key[8];
int pwdLen = strlen(passwd.buf);
for (int i=0; i<8; i++)
key[i] = i<pwdLen ? passwd.buf[i] : 0;
for (size_t i=0; i<8; i++)
key[i] = i<passwd.size() ? passwd[i] : 0;
deskey(key, EN0); deskey(key, EN0);
for (int j = 0; j < vncAuthChallengeSize; j += 8) for (int j = 0; j < vncAuthChallengeSize; j += 8)
des(challenge+j, challenge+j); des(challenge+j, challenge+j);

+ 3
- 5
common/rfb/ComparingUpdateTracker.cxx View File

void ComparingUpdateTracker::logStats() void ComparingUpdateTracker::logStats()
{ {
double ratio; double ratio;
char a[1024], b[1024];

siPrefix(totalPixels, "pixels", a, sizeof(a));
siPrefix(missedPixels, "pixels", b, sizeof(b));


ratio = (double)totalPixels / missedPixels; ratio = (double)totalPixels / missedPixels;


vlog.info("%s in / %s out", a, b);
vlog.info("%s in / %s out",
siPrefix(totalPixels, "pixels").c_str(),
siPrefix(missedPixels, "pixels").c_str());
vlog.info("(1:%g ratio)", ratio); vlog.info("(1:%g ratio)", ratio);


totalPixels = missedPixels = 0; totalPixels = missedPixels = 0;

+ 21
- 25
common/rfb/Configuration.cxx View File



fprintf(stderr, "%s Parameters:\n", name.buf); fprintf(stderr, "%s Parameters:\n", name.buf);
while (current) { while (current) {
char* def_str = current->getDefaultStr();
std::string def_str = current->getDefaultStr();
const char* desc = current->getDescription(); const char* desc = current->getDescription();
fprintf(stderr," %-*s -", nameWidth, current->getName()); fprintf(stderr," %-*s -", nameWidth, current->getName());
int column = strlen(current->getName()); int column = strlen(current->getName());
if (!s) break; if (!s) break;
} }


if (def_str) {
if (column + (int)strlen(def_str) + 11 > width)
if (!def_str.empty()) {
if (column + (int)def_str.size() + 11 > width)
fprintf(stderr,"\n%*s",nameWidth+4,""); fprintf(stderr,"\n%*s",nameWidth+4,"");
fprintf(stderr," (default=%s)\n",def_str);
strFree(def_str);
fprintf(stderr," (default=%s)\n",def_str.c_str());
} else { } else {
fprintf(stderr,"\n"); fprintf(stderr,"\n");
} }
return param->setParam(); return param->setParam();
} }


char*
AliasParameter::getDefaultStr() const {
return 0;
std::string AliasParameter::getDefaultStr() const {
return "";
} }


char* AliasParameter::getValueStr() const {
std::string AliasParameter::getValueStr() const {
return param->getValueStr(); return param->getValueStr();
} }


vlog.debug("set %s(Bool) to %d", getName(), value); vlog.debug("set %s(Bool) to %d", getName(), value);
} }


char*
BoolParameter::getDefaultStr() const {
return strDup(def_value ? "1" : "0");
std::string BoolParameter::getDefaultStr() const {
return def_value ? "1" : "0";
} }


char* BoolParameter::getValueStr() const {
return strDup(value ? "1" : "0");
std::string BoolParameter::getValueStr() const {
return value ? "1" : "0";
} }


bool BoolParameter::isBool() const { bool BoolParameter::isBool() const {
return true; return true;
} }


char*
IntParameter::getDefaultStr() const {
char* result = new char[16];
std::string IntParameter::getDefaultStr() const {
char result[16];
sprintf(result, "%d", def_value); sprintf(result, "%d", def_value);
return result; return result;
} }


char* IntParameter::getValueStr() const {
char* result = new char[16];
std::string IntParameter::getValueStr() const {
char result[16];
sprintf(result, "%d", value); sprintf(result, "%d", value);
return result; return result;
} }
return value != 0; return value != 0;
} }


char* StringParameter::getDefaultStr() const {
return strDup(def_value);
std::string StringParameter::getDefaultStr() const {
return def_value;
} }


char* StringParameter::getValueStr() const {
std::string StringParameter::getValueStr() const {
LOCK_CONFIG; LOCK_CONFIG;
return strDup(value);
return std::string(value);
} }


StringParameter::operator const char *() const { StringParameter::operator const char *() const {
} }
} }


char* BinaryParameter::getDefaultStr() const {
std::string BinaryParameter::getDefaultStr() const {
return binToHex(def_value, def_length); return binToHex(def_value, def_length);
} }


char* BinaryParameter::getValueStr() const {
std::string BinaryParameter::getValueStr() const {
LOCK_CONFIG; LOCK_CONFIG;
return binToHex(value, length); return binToHex(value, length);
} }

+ 12
- 16
common/rfb/Configuration.h View File



virtual bool setParam(const char* value) = 0; virtual bool setParam(const char* value) = 0;
virtual bool setParam(); virtual bool setParam();
virtual char* getDefaultStr() const = 0;
virtual char* getValueStr() const = 0;
virtual std::string getDefaultStr() const = 0;
virtual std::string getValueStr() const = 0;
virtual bool isBool() const; virtual bool isBool() const;


virtual void setImmutable(); virtual void setImmutable();
ConfigurationObject co=ConfGlobal); ConfigurationObject co=ConfGlobal);
virtual bool setParam(const char* value); virtual bool setParam(const char* value);
virtual bool setParam(); virtual bool setParam();
virtual char* getDefaultStr() const;
virtual char* getValueStr() const;
virtual std::string getDefaultStr() const;
virtual std::string getValueStr() const;
virtual bool isBool() const; virtual bool isBool() const;
virtual void setImmutable(); virtual void setImmutable();
private: private:
virtual bool setParam(const char* value); virtual bool setParam(const char* value);
virtual bool setParam(); virtual bool setParam();
virtual void setParam(bool b); virtual void setParam(bool b);
virtual char* getDefaultStr() const;
virtual char* getValueStr() const;
virtual std::string getDefaultStr() const;
virtual std::string getValueStr() const;
virtual bool isBool() const; virtual bool isBool() const;
operator bool() const; operator bool() const;
protected: protected:
using VoidParameter::setParam; using VoidParameter::setParam;
virtual bool setParam(const char* value); virtual bool setParam(const char* value);
virtual bool setParam(int v); virtual bool setParam(int v);
virtual char* getDefaultStr() const;
virtual char* getValueStr() const;
virtual std::string getDefaultStr() const;
virtual std::string getValueStr() const;
operator int() const; operator int() const;
protected: protected:
int value; int value;
ConfigurationObject co=ConfGlobal); ConfigurationObject co=ConfGlobal);
virtual ~StringParameter(); virtual ~StringParameter();
virtual bool setParam(const char* value); virtual bool setParam(const char* value);
virtual char* getDefaultStr() const;
virtual char* getValueStr() const;
virtual std::string getDefaultStr() const;
virtual std::string getValueStr() const;
operator const char*() const; operator const char*() const;

// getData() returns a copy of the data - it must be delete[]d by the
// caller.
char* getData() const { return getValueStr(); }
protected: protected:
char* value; char* value;
char* def_value; char* def_value;
virtual ~BinaryParameter(); virtual ~BinaryParameter();
virtual bool setParam(const char* value); virtual bool setParam(const char* value);
virtual void setParam(const uint8_t* v, size_t l); virtual void setParam(const uint8_t* v, size_t l);
virtual char* getDefaultStr() const;
virtual char* getValueStr() const;
virtual std::string getDefaultStr() const;
virtual std::string getValueStr() const;


std::vector<uint8_t> getData() const; std::vector<uint8_t> getData() const;



+ 9
- 12
common/rfb/DecodeManager.cxx View File



double ratio; double ratio;


char a[1024], b[1024];

rects = 0; rects = 0;
pixels = bytes = equivalent = 0; pixels = bytes = equivalent = 0;




ratio = (double)stats[i].equivalent / stats[i].bytes; ratio = (double)stats[i].equivalent / stats[i].bytes;


siPrefix(stats[i].rects, "rects", a, sizeof(a));
siPrefix(stats[i].pixels, "pixels", b, sizeof(b));
vlog.info(" %s: %s, %s", encodingName(i), a, b);
iecPrefix(stats[i].bytes, "B", a, sizeof(a));
vlog.info(" %s: %s, %s", encodingName(i),
siPrefix(stats[i].rects, "rects").c_str(),
siPrefix(stats[i].pixels, "pixels").c_str());
vlog.info(" %*s %s (1:%g ratio)", vlog.info(" %*s %s (1:%g ratio)",
(int)strlen(encodingName(i)), "", (int)strlen(encodingName(i)), "",
a, ratio);
iecPrefix(stats[i].bytes, "B").c_str(), ratio);
} }


ratio = (double)equivalent / bytes; ratio = (double)equivalent / bytes;


siPrefix(rects, "rects", a, sizeof(a));
siPrefix(pixels, "pixels", b, sizeof(b));
vlog.info(" Total: %s, %s", a, b);
iecPrefix(bytes, "B", a, sizeof(a));
vlog.info(" %s (1:%g ratio)", a, ratio);
vlog.info(" Total: %s, %s",
siPrefix(rects, "rects").c_str(),
siPrefix(pixels, "pixels").c_str());
vlog.info(" %s (1:%g ratio)",
iecPrefix(bytes, "B").c_str(), ratio);
} }


void DecodeManager::setThreadException(const rdr::Exception& e) void DecodeManager::setThreadException(const rdr::Exception& e)

+ 13
- 17
common/rfb/EncodeManager.cxx View File



double ratio; double ratio;


char a[1024], b[1024];

rects = 0; rects = 0;
pixels = bytes = equivalent = 0; pixels = bytes = equivalent = 0;




ratio = (double)copyStats.equivalent / copyStats.bytes; ratio = (double)copyStats.equivalent / copyStats.bytes;


siPrefix(copyStats.rects, "rects", a, sizeof(a));
siPrefix(copyStats.pixels, "pixels", b, sizeof(b));
vlog.info(" %s: %s, %s", "Copies", a, b);
iecPrefix(copyStats.bytes, "B", a, sizeof(a));
vlog.info(" %s: %s, %s", "Copies",
siPrefix(copyStats.rects, "rects").c_str(),
siPrefix(copyStats.pixels, "pixels").c_str());
vlog.info(" %*s %s (1:%g ratio)", vlog.info(" %*s %s (1:%g ratio)",
(int)strlen("Copies"), "", (int)strlen("Copies"), "",
a, ratio);
iecPrefix(copyStats.bytes, "B").c_str(), ratio);
} }


for (i = 0;i < stats.size();i++) { for (i = 0;i < stats.size();i++) {


ratio = (double)stats[i][j].equivalent / stats[i][j].bytes; ratio = (double)stats[i][j].equivalent / stats[i][j].bytes;


siPrefix(stats[i][j].rects, "rects", a, sizeof(a));
siPrefix(stats[i][j].pixels, "pixels", b, sizeof(b));
vlog.info(" %s: %s, %s", encoderTypeName((EncoderType)j), a, b);
iecPrefix(stats[i][j].bytes, "B", a, sizeof(a));
vlog.info(" %s: %s, %s", encoderTypeName((EncoderType)j),
siPrefix(stats[i][j].rects, "rects").c_str(),
siPrefix(stats[i][j].pixels, "pixels").c_str());
vlog.info(" %*s %s (1:%g ratio)", vlog.info(" %*s %s (1:%g ratio)",
(int)strlen(encoderTypeName((EncoderType)j)), "", (int)strlen(encoderTypeName((EncoderType)j)), "",
a, ratio);
iecPrefix(stats[i][j].bytes, "B").c_str(), ratio);
} }
} }


ratio = (double)equivalent / bytes; ratio = (double)equivalent / bytes;


siPrefix(rects, "rects", a, sizeof(a));
siPrefix(pixels, "pixels", b, sizeof(b));
vlog.info(" Total: %s, %s", a, b);
iecPrefix(bytes, "B", a, sizeof(a));
vlog.info(" %s (1:%g ratio)", a, ratio);
vlog.info(" Total: %s, %s",
siPrefix(rects, "rects").c_str(),
siPrefix(pixels, "pixels").c_str());
vlog.info(" %s (1:%g ratio)",
iecPrefix(bytes, "B").c_str(), ratio);
} }


bool EncodeManager::supported(int encoding) bool EncodeManager::supported(int encoding)

+ 6
- 9
common/rfb/Hostname.h View File

return true; return true;
} }


static void getHostAndPort(const char* hi, char** host, int* port, int basePort=5900) {
static void getHostAndPort(const char* hi, std::string* host,
int* port, int basePort=5900)
{
const char* hostStart; const char* hostStart;
const char* hostEnd; const char* hostEnd;
const char* portStart; const char* portStart;
hostEnd--; hostEnd--;


if (hostStart == hostEnd) if (hostStart == hostEnd)
*host = strDup("localhost");
else {
size_t len;
len = hostEnd - hostStart + 1;
*host = new char[len];
strncpy(*host, hostStart, len-1);
(*host)[len-1] = '\0';
}
*host = "localhost";
else
*host = std::string(hostStart, hostEnd - hostStart);


if (portStart == NULL) if (portStart == NULL)
*port = basePort; *port = basePort;

+ 1
- 1
common/rfb/LogWriter.cxx View File

LogWriter::setLogParams("*::0"); LogWriter::setLogParams("*::0");
StringParameter::setParam(v); StringParameter::setParam(v);
CharArray logParam; CharArray logParam;
CharArray params(getData());
CharArray params(strDup(getValueStr().c_str()));
while (params.buf) { while (params.buf) {
strSplit(params.buf, ',', &logParam.buf, &params.buf); strSplit(params.buf, ',', &logParam.buf, &params.buf);
if (strlen(logParam.buf) && !LogWriter::setLogParams(logParam.buf)) if (strlen(logParam.buf) && !LogWriter::setLogParams(logParam.buf))

+ 8
- 7
common/rfb/SConnection.cxx View File

strFree(clientClipboard); strFree(clientClipboard);
clientClipboard = NULL; clientClipboard = NULL;


clientClipboard = latin1ToUTF8(str);
clientClipboard = strDup(latin1ToUTF8(str).c_str());


handleClipboardAnnounce(true); handleClipboardAnnounce(true);
} }
strFree(clientClipboard); strFree(clientClipboard);
clientClipboard = NULL; clientClipboard = NULL;


clientClipboard = convertLF((const char*)data[0], lengths[0]);
std::string filtered(convertLF((const char*)data[0], lengths[0]));
clientClipboard = strDup(filtered.c_str());


// FIXME: Should probably verify that this data was actually requested // FIXME: Should probably verify that this data was actually requested
handleClipboardData(clientClipboard); handleClipboardData(clientClipboard);
{ {
if (client.supportsEncoding(pseudoEncodingExtendedClipboard) && if (client.supportsEncoding(pseudoEncodingExtendedClipboard) &&
(client.clipboardFlags() & rfb::clipboardProvide)) { (client.clipboardFlags() & rfb::clipboardProvide)) {
CharArray filtered(convertCRLF(data));
size_t sizes[1] = { strlen(filtered.buf) + 1 };
const uint8_t* data[1] = { (const uint8_t*)filtered.buf };
std::string filtered(convertCRLF(data));
size_t sizes[1] = { filtered.size() + 1 };
const uint8_t* data[1] = { (const uint8_t*)filtered.c_str() };


if (unsolicitedClipboardAttempt) { if (unsolicitedClipboardAttempt) {
unsolicitedClipboardAttempt = false; unsolicitedClipboardAttempt = false;


writer()->writeClipboardProvide(rfb::clipboardUTF8, sizes, data); writer()->writeClipboardProvide(rfb::clipboardUTF8, sizes, data);
} else { } else {
CharArray latin1(utf8ToLatin1(data));
std::string latin1(utf8ToLatin1(data));


writer()->writeServerCutText(latin1.buf);
writer()->writeServerCutText(latin1.c_str());
} }
} }



+ 1
- 4
common/rfb/SMsgHandler.cxx View File

if (lengths[i] == 0) if (lengths[i] == 0)
vlog.debug(" %s (only notify)", type); vlog.debug(" %s (only notify)", type);
else { else {
char bytes[1024];

iecPrefix(lengths[i], "B", bytes, sizeof(bytes));
vlog.debug(" %s (automatically send up to %s)", vlog.debug(" %s (automatically send up to %s)",
type, bytes);
type, iecPrefix(lengths[i], "B").c_str());
} }
} }
} }

+ 2
- 2
common/rfb/SMsgReader.cxx View File



CharArray ca(len); CharArray ca(len);
is->readBytes(ca.buf, len); is->readBytes(ca.buf, len);
CharArray filtered(convertLF(ca.buf, len));
handler->clientCutText(filtered.buf);
std::string filtered(convertLF(ca.buf, len));
handler->clientCutText(filtered.c_str());


return true; return true;
} }

+ 2
- 1
common/rfb/SSecurityPlain.cxx View File



bool PasswordValidator::validUser(const char* username) bool PasswordValidator::validUser(const char* username)
{ {
CharArray users(plainUsers.getValueStr()), user;
CharArray users(strDup(plainUsers.getValueStr().c_str()));
CharArray user;


while (users.buf) { while (users.buf) {
strSplit(users.buf, ',', &user.buf, &users.buf); strSplit(users.buf, ',', &user.buf, &users.buf);

+ 7
- 3
common/rfb/UserPasswdGetter.h View File

*/ */
#ifndef __RFB_USERPASSWDGETTER_H__ #ifndef __RFB_USERPASSWDGETTER_H__
#define __RFB_USERPASSWDGETTER_H__ #define __RFB_USERPASSWDGETTER_H__

#include <string>

namespace rfb { namespace rfb {
class UserPasswdGetter { class UserPasswdGetter {
public: public:
// getUserPasswd gets the username and password. This might involve a // getUserPasswd gets the username and password. This might involve a
// dialog, getpass(), etc. The user buffer pointer can be null, in which // dialog, getpass(), etc. The user buffer pointer can be null, in which
// case no user name will be retrieved. The caller MUST delete [] the
// result(s).
virtual void getUserPasswd(bool secure, char** user, char** password)=0;
// case no user name will be retrieved.
virtual void getUserPasswd(bool secure, std::string* user,
std::string* password)=0;


virtual ~UserPasswdGetter() {} virtual ~UserPasswdGetter() {}
}; };
} }

#endif #endif

+ 74
- 102
common/rfb/util.cxx View File

delete [] s; delete [] s;
} }


void strFree(wchar_t* s) {
delete [] s;
}



bool strSplit(const char* src, const char limiter, char** out1, char** out2, bool fromEnd) { bool strSplit(const char* src, const char limiter, char** out1, char** out2, bool fromEnd) {
CharArray out1old, out2old; CharArray out1old, out2old;
} }
} }


char* binToHex(const uint8_t* in, size_t inlen) {
char* out = new char[inlen*2+1]();
binToHex(in, inlen, out, inlen*2);
std::string binToHex(const uint8_t* in, size_t inlen) {
char* buffer = new char[inlen*2+1]();
std::string out;
binToHex(in, inlen, buffer, inlen*2);
out = buffer;
delete [] buffer;
return out; return out;
} }


return out; return out;
} }


char* convertLF(const char* src, size_t bytes)
std::string convertLF(const char* src, size_t bytes)
{ {
char* buffer;
size_t sz; size_t sz;
std::string out;


char* out;
const char* in; const char* in;
size_t in_len; size_t in_len;


// Always include space for a NULL
sz = 1;

// Compute output size // Compute output size
sz = 0;
in = src; in = src;
in_len = bytes; in_len = bytes;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
in_len--; in_len--;
} }


// Alloc
buffer = new char[sz];
memset(buffer, 0, sz);
// Reserve space
out.reserve(sz);


// And convert // And convert
out = buffer;
in = src; in = src;
in_len = bytes; in_len = bytes;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
if (*in != '\r') { if (*in != '\r') {
*out++ = *in++;
out += *in++;
in_len--; in_len--;
continue; continue;
} }


if ((in_len < 2) || (*(in+1) != '\n')) if ((in_len < 2) || (*(in+1) != '\n'))
*out++ = '\n';
out += '\n';


in++; in++;
in_len--; in_len--;
} }


return buffer;
return out;
} }


char* convertCRLF(const char* src, size_t bytes)
std::string convertCRLF(const char* src, size_t bytes)
{ {
char* buffer;
std::string out;
size_t sz; size_t sz;


char* out;
const char* in; const char* in;
size_t in_len; size_t in_len;


// Always include space for a NULL
sz = 1;

// Compute output size // Compute output size
sz = 0;
in = src; in = src;
in_len = bytes; in_len = bytes;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
in_len--; in_len--;
} }


// Alloc
buffer = new char[sz];
memset(buffer, 0, sz);
// Reserve space
out.reserve(sz);


// And convert // And convert
out = buffer;
in = src; in = src;
in_len = bytes; in_len = bytes;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
if (*in == '\n') { if (*in == '\n') {
if ((in == src) || (*(in-1) != '\r')) if ((in == src) || (*(in-1) != '\r'))
*out++ = '\r';
out += '\r';
} }


*out = *in;
out += *in;


if (*in == '\r') { if (*in == '\r') {
if ((in_len < 2) || (*(in+1) != '\n')) {
out++;
*out = '\n';
}
if ((in_len < 2) || (*(in+1) != '\n'))
out += '\n';
} }


out++;
in++; in++;
in_len--; in_len--;
} }


return buffer;
return out;
} }


size_t ucs4ToUTF8(unsigned src, char dst[5]) { size_t ucs4ToUTF8(unsigned src, char dst[5]) {
return 2; return 2;
} }


char* latin1ToUTF8(const char* src, size_t bytes) {
char* buffer;
std::string latin1ToUTF8(const char* src, size_t bytes) {
std::string out;
size_t sz; size_t sz;


char* out;
const char* in; const char* in;
size_t in_len; size_t in_len;


// Always include space for a NULL
sz = 1;

// Compute output size // Compute output size
sz = 0;
in = src; in = src;
in_len = bytes; in_len = bytes;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
in_len--; in_len--;
} }


// Alloc
buffer = new char[sz];
memset(buffer, 0, sz);
// Reserve space
out.reserve(sz);


// And convert // And convert
out = buffer;
in = src; in = src;
in_len = bytes; in_len = bytes;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
out += ucs4ToUTF8(*(const unsigned char*)in, out);
char buf[5];
ucs4ToUTF8(*(const unsigned char*)in, buf);
out += buf;
in++; in++;
in_len--; in_len--;
} }


return buffer;
return out;
} }


char* utf8ToLatin1(const char* src, size_t bytes) {
char* buffer;
std::string utf8ToLatin1(const char* src, size_t bytes) {
std::string out;
size_t sz; size_t sz;


char* out;
const char* in; const char* in;
size_t in_len; size_t in_len;


// Always include space for a NULL
sz = 1;

// Compute output size // Compute output size
sz = 0;
in = src; in = src;
in_len = bytes; in_len = bytes;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
sz++; sz++;
} }


// Alloc
buffer = new char[sz];
memset(buffer, 0, sz);
// Reserve space
out.reserve(sz);


// And convert // And convert
out = buffer;
in = src; in = src;
in_len = bytes; in_len = bytes;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
in_len -= len; in_len -= len;


if (ucs > 0xff) if (ucs > 0xff)
*out++ = '?';
out += '?';
else else
*out++ = (unsigned char)ucs;
out += (unsigned char)ucs;
} }


return buffer;
return out;
} }


char* utf16ToUTF8(const wchar_t* src, size_t units)
std::string utf16ToUTF8(const wchar_t* src, size_t units)
{ {
char* buffer;
std::string out;
size_t sz; size_t sz;


char* out;
const wchar_t* in; const wchar_t* in;
size_t in_len; size_t in_len;


// Always include space for a NULL
sz = 1;

// Compute output size // Compute output size
sz = 0;
in = src; in = src;
in_len = units; in_len = units;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
sz += ucs4ToUTF8(ucs, buf); sz += ucs4ToUTF8(ucs, buf);
} }


// Alloc
buffer = new char[sz];
memset(buffer, 0, sz);
// Reserve space
out.reserve(sz);


// And convert // And convert
out = buffer;
in = src; in = src;
in_len = units; in_len = units;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
size_t len; size_t len;
unsigned ucs; unsigned ucs;
char buf[5];


len = utf16ToUCS4(in, in_len, &ucs); len = utf16ToUCS4(in, in_len, &ucs);
in += len; in += len;
in_len -= len; in_len -= len;


out += ucs4ToUTF8(ucs, out);
ucs4ToUTF8(ucs, buf);
out += buf;
} }


return buffer;
return out;
} }


wchar_t* utf8ToUTF16(const char* src, size_t bytes)
std::wstring utf8ToUTF16(const char* src, size_t bytes)
{ {
wchar_t* buffer;
std::wstring out;
size_t sz; size_t sz;


wchar_t* out;
const char* in; const char* in;
size_t in_len; size_t in_len;


// Always include space for a NULL
sz = 1;

// Compute output size // Compute output size
sz = 0;
in = src; in = src;
in_len = bytes; in_len = bytes;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
sz += ucs4ToUTF16(ucs, buf); sz += ucs4ToUTF16(ucs, buf);
} }


// Alloc
buffer = new wchar_t[sz];
memset(buffer, 0, sz * sizeof(wchar_t));
// Reserve space
out.reserve(sz);


// And convert // And convert
out = buffer;
in = src; in = src;
in_len = bytes; in_len = bytes;
while ((in_len > 0) && (*in != '\0')) { while ((in_len > 0) && (*in != '\0')) {
size_t len; size_t len;
unsigned ucs; unsigned ucs;
wchar_t buf[3];


len = utf8ToUCS4(in, in_len, &ucs); len = utf8ToUCS4(in, in_len, &ucs);
in += len; in += len;
in_len -= len; in_len -= len;


out += ucs4ToUTF16(ucs, out);
ucs4ToUTF16(ucs, buf);
out += buf;
} }


return buffer;
return out;
} }


unsigned msBetween(const struct timeval *first, unsigned msBetween(const struct timeval *first,
return false; return false;
} }


static size_t doPrefix(long long value, const char *unit,
char *buffer, size_t maxlen,
unsigned divisor, const char **prefixes,
size_t prefixCount, int precision) {
static std::string doPrefix(long long value, const char *unit,
unsigned divisor, const char **prefixes,
size_t prefixCount, int precision) {
char buffer[256];
double newValue; double newValue;
size_t prefix, len;
size_t prefix;


newValue = value; newValue = value;
prefix = 0; prefix = 0;
prefix++; prefix++;
} }


len = snprintf(buffer, maxlen, "%.*g %s%s", precision, newValue,
(prefix == 0) ? "" : prefixes[prefix-1], unit);
buffer[maxlen-1] = '\0';
snprintf(buffer, sizeof(buffer), "%.*g %s%s", precision, newValue,
(prefix == 0) ? "" : prefixes[prefix-1], unit);
buffer[sizeof(buffer)-1] = '\0';


return len;
return buffer;
} }


static const char *siPrefixes[] = static const char *siPrefixes[] =
static const char *iecPrefixes[] = static const char *iecPrefixes[] =
{ "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" }; { "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" };


size_t siPrefix(long long value, const char *unit,
char *buffer, size_t maxlen, int precision) {
return doPrefix(value, unit, buffer, maxlen, 1000, siPrefixes,
std::string siPrefix(long long value, const char *unit,
int precision) {
return doPrefix(value, unit, 1000, siPrefixes,
sizeof(siPrefixes)/sizeof(*siPrefixes), sizeof(siPrefixes)/sizeof(*siPrefixes),
precision); precision);
} }


size_t iecPrefix(long long value, const char *unit,
char *buffer, size_t maxlen, int precision) {
return doPrefix(value, unit, buffer, maxlen, 1024, iecPrefixes,
std::string iecPrefix(long long value, const char *unit,
int precision) {
return doPrefix(value, unit, 1024, iecPrefixes,
sizeof(iecPrefixes)/sizeof(*iecPrefixes), sizeof(iecPrefixes)/sizeof(*iecPrefixes),
precision); precision);
} }

+ 13
- 14
common/rfb/util.h View File

#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>


#include <string>
#include <vector> #include <vector>


struct timeval; struct timeval;


char* strDup(const char* s); char* strDup(const char* s);
void strFree(char* s); void strFree(char* s);
void strFree(wchar_t* s);


// Returns true if split successful. Returns false otherwise. // Returns true if split successful. Returns false otherwise.
// ALWAYS *copies* first part of string to out1 buffer. // ALWAYS *copies* first part of string to out1 buffer.
// Conversion to and from a hex string // Conversion to and from a hex string


void binToHex(const uint8_t* in, size_t inlen, char* out, size_t outlen); void binToHex(const uint8_t* in, size_t inlen, char* out, size_t outlen);
char* binToHex(const uint8_t* in, size_t inlen);
std::string binToHex(const uint8_t* in, size_t inlen);
bool hexToBin(const char* in, size_t inlen, uint8_t* out, size_t outlen); bool hexToBin(const char* in, size_t inlen, uint8_t* out, size_t outlen);
std::vector<uint8_t> hexToBin(const char* in, size_t inlen); std::vector<uint8_t> hexToBin(const char* in, size_t inlen);


// Makes sure line endings are in a certain format // Makes sure line endings are in a certain format


char* convertLF(const char* src, size_t bytes = (size_t)-1);
char* convertCRLF(const char* src, size_t bytes = (size_t)-1);
std::string convertLF(const char* src, size_t bytes = (size_t)-1);
std::string convertCRLF(const char* src, size_t bytes = (size_t)-1);


// Convertions between various Unicode formats. The returned strings are
// always null terminated and must be freed using strFree().
// Convertions between various Unicode formats


size_t ucs4ToUTF8(unsigned src, char dst[5]); size_t ucs4ToUTF8(unsigned src, char dst[5]);
size_t utf8ToUCS4(const char* src, size_t max, unsigned* dst); size_t utf8ToUCS4(const char* src, size_t max, unsigned* dst);
size_t ucs4ToUTF16(unsigned src, wchar_t dst[3]); size_t ucs4ToUTF16(unsigned src, wchar_t dst[3]);
size_t utf16ToUCS4(const wchar_t* src, size_t max, unsigned* dst); size_t utf16ToUCS4(const wchar_t* src, size_t max, unsigned* dst);


char* latin1ToUTF8(const char* src, size_t bytes = (size_t)-1);
char* utf8ToLatin1(const char* src, size_t bytes = (size_t)-1);
std::string latin1ToUTF8(const char* src, size_t bytes = (size_t)-1);
std::string utf8ToLatin1(const char* src, size_t bytes = (size_t)-1);


char* utf16ToUTF8(const wchar_t* src, size_t units = (size_t)-1);
wchar_t* utf8ToUTF16(const char* src, size_t bytes = (size_t)-1);
std::string utf16ToUTF8(const wchar_t* src, size_t units = (size_t)-1);
std::wstring utf8ToUTF16(const char* src, size_t bytes = (size_t)-1);


// HELPER functions for timeout handling // HELPER functions for timeout handling


bool isBefore(const struct timeval *first, bool isBefore(const struct timeval *first,
const struct timeval *second); const struct timeval *second);


size_t siPrefix(long long value, const char *unit,
char *buffer, size_t maxlen, int precision=6);
size_t iecPrefix(long long value, const char *unit,
char *buffer, size_t maxlen, int precision=6);
std::string siPrefix(long long value, const char *unit,
int precision=6);
std::string iecPrefix(long long value, const char *unit,
int precision=6);
} }


// Some platforms (e.g. Windows) include max() and min() macros in their // Some platforms (e.g. Windows) include max() and min() macros in their

+ 3
- 6
tests/perf/fbperf.cxx View File

double time[3]; double time[3];


double delay, rate; double delay, rate;
char s[1024];


// Run the test several times at different resolutions... // Run the test several times at different resolutions...
dosubtest(win, 800, 600, &pixels[0], &frames[0], &time[0]); dosubtest(win, 800, 600, &pixels[0], &frames[0], &time[0]);
} }


fprintf(stderr, "Rendering delay: %g ms/frame\n", delay * 1000.0); fprintf(stderr, "Rendering delay: %g ms/frame\n", delay * 1000.0);
if (rate == 0.0)
strcpy(s, "N/A pixels/s");
else
rfb::siPrefix(1.0 / rate, "pixels/s", s, sizeof(s));
fprintf(stderr, "Rendering rate: %s\n", s);
fprintf(stderr, "Rendering rate: %s\n",
(rate == 0.0) ? "N/A pixels/s" :
rfb::siPrefix(1.0 / rate, "pixels/s").c_str());
fprintf(stderr, "Maximum FPS: %g fps @ 1920x1080\n", fprintf(stderr, "Maximum FPS: %g fps @ 1920x1080\n",
1.0 / (delay + rate * 1920 * 1080)); 1.0 / (delay + rate * 1920 * 1080));
} }

+ 6
- 10
tests/unit/convertlf.cxx View File



static void testLF(const char* input, const char* expected) static void testLF(const char* input, const char* expected)
{ {
char* output;
std::string output;


printf("convertLF(\"%s\"): ", escape(input)); printf("convertLF(\"%s\"): ", escape(input));


output = rfb::convertLF(input); output = rfb::convertLF(input);


if (strcmp(output, expected) != 0)
printf("FAILED: got \"%s\"", escape(output));
if (output != expected)
printf("FAILED: got \"%s\"", escape(output.c_str()));
else else
printf("OK"); printf("OK");
printf("\n"); printf("\n");
fflush(stdout); fflush(stdout);

rfb::strFree(output);
} }


static void testCRLF(const char* input, const char* expected) static void testCRLF(const char* input, const char* expected)
{ {
char* output;
std::string output;


printf("convertCRLF(\"%s\"): ", escape(input)); printf("convertCRLF(\"%s\"): ", escape(input));


output = rfb::convertCRLF(input); output = rfb::convertCRLF(input);


if (strcmp(output, expected) != 0)
printf("FAILED: got \"%s\"", escape(output));
if (output != expected)
printf("FAILED: got \"%s\"", escape(output.c_str()));
else else
printf("OK"); printf("OK");
printf("\n"); printf("\n");
fflush(stdout); fflush(stdout);

rfb::strFree(output);
} }


int main(int /*argc*/, char** /*argv*/) int main(int /*argc*/, char** /*argv*/)

+ 3
- 5
tests/unit/hostport.cxx View File

static void doTest(const char* hostAndPort, static void doTest(const char* hostAndPort,
const char* expectedHost, int expectedPort) const char* expectedHost, int expectedPort)
{ {
char* host;
std::string host;
int port; int port;


printf("\"%s\": ", hostAndPort); printf("\"%s\": ", hostAndPort);


rfb::getHostAndPort(hostAndPort, &host, &port); rfb::getHostAndPort(hostAndPort, &host, &port);


if (strcmp(host, expectedHost) != 0)
printf("FAILED (\"%s\" != \"%s\")", host, expectedHost);
if (host != expectedHost)
printf("FAILED (\"%s\" != \"%s\")", host.c_str(), expectedHost);
else if (port != expectedPort) else if (port != expectedPort)
printf("FAILED (%d != %d)", port, expectedPort); printf("FAILED (%d != %d)", port, expectedPort);
else else
printf("OK"); printf("OK");
printf("\n"); printf("\n");
fflush(stdout); fflush(stdout);

rfb::strFree(host);
} }


int main(int /*argc*/, char** /*argv*/) int main(int /*argc*/, char** /*argv*/)

+ 6
- 10
tests/unit/unicode.cxx View File

unsigned ucs4; unsigned ucs4;
char utf8[5]; char utf8[5];
wchar_t utf16[3]; wchar_t utf16[3];
char *out;
wchar_t *wout;
std::string out;
std::wstring wout;
size_t len; size_t len;


failures = 0; failures = 0;
continue; continue;


out = rfb::latin1ToUTF8(latin1utf8[i].latin1); out = rfb::latin1ToUTF8(latin1utf8[i].latin1);
if (strcmp(out, latin1utf8[i].utf8) != 0) {
if (out != latin1utf8[i].utf8) {
printf("FAILED: latin1ToUTF8() #%d\n", (int)i+1); printf("FAILED: latin1ToUTF8() #%d\n", (int)i+1);
failures++; failures++;
} }
rfb::strFree(out);
} }


for (i = 0;i < ARRAY_SIZE(latin1utf8);i++) { for (i = 0;i < ARRAY_SIZE(latin1utf8);i++) {
out = rfb::utf8ToLatin1(latin1utf8[i].utf8); out = rfb::utf8ToLatin1(latin1utf8[i].utf8);
if (strcmp(out, latin1utf8[i].latin1) != 0) {
if (out != latin1utf8[i].latin1) {
printf("FAILED: utf8ToLatin1() #%d\n", (int)i+1); printf("FAILED: utf8ToLatin1() #%d\n", (int)i+1);
failures++; failures++;
} }
rfb::strFree(out);
} }


for (i = 0;i < ARRAY_SIZE(utf8utf16);i++) { for (i = 0;i < ARRAY_SIZE(utf8utf16);i++) {
continue; continue;


out = rfb::utf16ToUTF8(utf8utf16[i].utf16); out = rfb::utf16ToUTF8(utf8utf16[i].utf16);
if (strcmp(out, utf8utf16[i].utf8) != 0) {
if (out != utf8utf16[i].utf8) {
printf("FAILED: utf16ToUTF8() #%d\n", (int)i+1); printf("FAILED: utf16ToUTF8() #%d\n", (int)i+1);
failures++; failures++;
} }
rfb::strFree(out);
} }


for (i = 0;i < ARRAY_SIZE(utf8utf16);i++) { for (i = 0;i < ARRAY_SIZE(utf8utf16);i++) {
continue; continue;


wout = rfb::utf8ToUTF16(utf8utf16[i].utf8); wout = rfb::utf8ToUTF16(utf8utf16[i].utf8);
if (wcscmp(wout, utf8utf16[i].utf16) != 0) {
if (wout != utf8utf16[i].utf16) {
printf("FAILED: utf8ToUTF16() #%d\n", (int)i+1); printf("FAILED: utf8ToUTF16() #%d\n", (int)i+1);
failures++; failures++;
} }
rfb::strFree(wout);
} }


if (failures == 0) { if (failures == 0) {

+ 5
- 15
unix/xserver/hw/vnc/RFBGlue.cc View File



char* vncGetParam(const char *name) char* vncGetParam(const char *name)
{ {
rfb::VoidParameter *param;
char *value;
char *ret;
VoidParameter *param;


// Hack to avoid exposing password! // Hack to avoid exposing password!
if (strcasecmp(name, "Password") == 0) if (strcasecmp(name, "Password") == 0)
if (param == NULL) if (param == NULL)
return NULL; return NULL;


value = param->getValueStr();
if (value == NULL)
return NULL;

ret = strdup(value);

delete [] value;

return ret;
return strdup(param->getValueStr().c_str());
} }


const char* vncGetParamDesc(const char *name) const char* vncGetParamDesc(const char *name)
char* vncConvertLF(const char* src, size_t bytes) char* vncConvertLF(const char* src, size_t bytes)
{ {
try { try {
return convertLF(src, bytes);
return strDup(convertLF(src, bytes).c_str());
} catch (...) { } catch (...) {
return NULL; return NULL;
} }
char* vncLatin1ToUTF8(const char* src, size_t bytes) char* vncLatin1ToUTF8(const char* src, size_t bytes)
{ {
try { try {
return latin1ToUTF8(src, bytes);
return strDup(latin1ToUTF8(src, bytes).c_str());
} catch (...) { } catch (...) {
return NULL; return NULL;
} }
char* vncUTF8ToLatin1(const char* src, size_t bytes) char* vncUTF8ToLatin1(const char* src, size_t bytes)
{ {
try { try {
return utf8ToLatin1(src, bytes);
return strDup(utf8ToLatin1(src, bytes).c_str());
} catch (...) { } catch (...) {
return NULL; return NULL;
} }

+ 2
- 3
unix/xserver/hw/vnc/vncExtInit.cc View File

return 0; return 0;
} }


char *host;
std::string host;
int port; int port;


getHostAndPort(addr, &host, &port, 5500); getHostAndPort(addr, &host, &port, 5500);


try { try {
network::Socket* sock = new network::TcpSocket(host, port);
delete [] host;
network::Socket* sock = new network::TcpSocket(host.c_str(), port);
desktop[0]->addClient(sock, true); desktop[0]->addClient(sock, true);
} catch (rdr::Exception& e) { } catch (rdr::Exception& e) {
vlog.error("Reverse connection: %s",e.str()); vlog.error("Reverse connection: %s",e.str());

+ 8
- 9
vncviewer/CConn.cxx View File

static const unsigned bpsEstimateWindow = 1000; static const unsigned bpsEstimateWindow = 1000;


CConn::CConn(const char* vncServerName, network::Socket* socket=NULL) CConn::CConn(const char* vncServerName, network::Socket* socket=NULL)
: serverHost(0), serverPort(0), desktop(NULL),
updateCount(0), pixelCount(0),
: serverPort(0), desktop(NULL), updateCount(0), pixelCount(0),
lastServerEncoding((unsigned int)-1), bpsEstimate(20000000) lastServerEncoding((unsigned int)-1), bpsEstimate(20000000)
{ {
setShared(::shared); setShared(::shared);
#ifndef WIN32 #ifndef WIN32
if (strchr(vncServerName, '/') != NULL) { if (strchr(vncServerName, '/') != NULL) {
sock = new network::UnixSocket(vncServerName); sock = new network::UnixSocket(vncServerName);
serverHost = strDup(sock->getPeerAddress());
vlog.info(_("Connected to socket %s"), serverHost);
serverHost = sock->getPeerAddress();
vlog.info(_("Connected to socket %s"), serverHost.c_str());
} else } else
#endif #endif
{ {
getHostAndPort(vncServerName, &serverHost, &serverPort); getHostAndPort(vncServerName, &serverHost, &serverPort);


sock = new network::TcpSocket(serverHost, serverPort);
vlog.info(_("Connected to host %s port %d"), serverHost, serverPort);
sock = new network::TcpSocket(serverHost.c_str(), serverPort);
vlog.info(_("Connected to host %s port %d"),
serverHost.c_str(), serverPort);
} }
} catch (rdr::Exception& e) { } catch (rdr::Exception& e) {
vlog.error("%s", e.str()); vlog.error("%s", e.str());


Fl::add_fd(sock->getFd(), FL_READ | FL_EXCEPT, socketEvent, this); Fl::add_fd(sock->getFd(), FL_READ | FL_EXCEPT, socketEvent, this);


setServerName(serverHost);
setServerName(serverHost.c_str());
setStreams(&sock->inStream(), &sock->outStream()); setStreams(&sock->inStream(), &sock->outStream());


initialiseProtocol(); initialiseProtocol();
if (desktop) if (desktop)
delete desktop; delete desktop;


delete [] serverHost;
if (sock) if (sock)
Fl::remove_fd(sock->getFd()); Fl::remove_fd(sock->getFd());
delete sock; delete sock;
strcat(infoText, "\n"); strcat(infoText, "\n");


snprintf(scratch, sizeof(scratch), snprintf(scratch, sizeof(scratch),
_("Host: %.80s port: %d"), serverHost, serverPort);
_("Host: %.80s port: %d"), serverHost.c_str(), serverPort);
strcat(infoText, scratch); strcat(infoText, scratch);
strcat(infoText, "\n"); strcat(infoText, "\n");



+ 1
- 1
vncviewer/CConn.h View File

static void handleUpdateTimeout(void *data); static void handleUpdateTimeout(void *data);


private: private:
char* serverHost;
std::string serverHost;
int serverPort; int serverPort;
network::Socket* sock; network::Socket* sock;



+ 4
- 6
vncviewer/DesktopWindow.cxx View File

fl_draw(buffer, 5, statsHeight - 5); fl_draw(buffer, 5, statsHeight - 5);


fl_color(FL_YELLOW); fl_color(FL_YELLOW);
siPrefix(self->stats[statsCount-1].pps, "pix/s",
buffer, sizeof(buffer), 3);
fl_draw(buffer, 5 + (statsWidth-10)/3, statsHeight - 5);
fl_draw(siPrefix(self->stats[statsCount-1].pps, "pix/s").c_str(),
5 + (statsWidth-10)/3, statsHeight - 5);


fl_color(FL_RED); fl_color(FL_RED);
siPrefix(self->stats[statsCount-1].bps * 8, "bps",
buffer, sizeof(buffer), 3);
fl_draw(buffer, 5 + (statsWidth-10)*2/3, statsHeight - 5);
fl_draw(siPrefix(self->stats[statsCount-1].bps * 8, "bps").c_str(),
5 + (statsWidth-10)*2/3, statsHeight - 5);


image = surface->image(); image = surface->image();
delete surface; delete surface;

+ 8
- 8
vncviewer/UserDialog.cxx View File

#include <FL/Fl_Return_Button.H> #include <FL/Fl_Return_Button.H>
#include <FL/Fl_Pixmap.H> #include <FL/Fl_Pixmap.H>


#include <rfb/util.h>
#include <rfb/Password.h> #include <rfb/Password.h>
#include <rfb/Exception.h> #include <rfb/Exception.h>


{ {
} }


void UserDialog::getUserPasswd(bool secure, char** user, char** password)
void UserDialog::getUserPasswd(bool secure, std::string* user,
std::string* password)
{ {
const char *passwordFileName(passwordFile); const char *passwordFileName(passwordFile);


char *envPassword = getenv("VNC_PASSWORD"); char *envPassword = getenv("VNC_PASSWORD");


if(user && envUsername && envPassword) { if(user && envUsername && envPassword) {
*user = strdup(envUsername);
*password = strdup(envPassword);
*user = envUsername;
*password = envPassword;
return; return;
} }


if (!user && envPassword) { if (!user && envPassword) {
*password = strdup(envPassword);
*password = envPassword;
return; return;
} }


fclose(fp); fclose(fp);


PlainPasswd passwd(obfPwd); PlainPasswd passwd(obfPwd);
*password = passwd.takeBuf();
*password = passwd.buf;


return; return;
} }


if (ret_val == 0) { if (ret_val == 0) {
if (user) if (user)
*user = strDup(username->value());
*password = strDup(passwd->value());
*user = username->value();
*password = passwd->value();
} }


delete win; delete win;

+ 2
- 1
vncviewer/UserDialog.h View File



// UserPasswdGetter callbacks // UserPasswdGetter callbacks


void getUserPasswd(bool secure, char** user, char** password);
void getUserPasswd(bool secure, std::string* user,
std::string* password);


// UserMsgBox callbacks // UserMsgBox callbacks



+ 3
- 5
vncviewer/Viewport.cxx View File



int Viewport::handle(int event) int Viewport::handle(int event)
{ {
char *filtered;
std::string filtered;
int buttonMask, wheelMask; int buttonMask, wheelMask;
DownMap::const_iterator iter; DownMap::const_iterator iter;


case FL_PASTE: case FL_PASTE:
filtered = convertLF(Fl::event_text(), Fl::event_length()); filtered = convertLF(Fl::event_text(), Fl::event_length());


vlog.debug("Sending clipboard data (%d bytes)", (int)strlen(filtered));
vlog.debug("Sending clipboard data (%d bytes)", (int)filtered.size());


try { try {
cc->sendClipboardData(filtered);
cc->sendClipboardData(filtered.c_str());
} catch (rdr::Exception& e) { } catch (rdr::Exception& e) {
vlog.error("%s", e.str()); vlog.error("%s", e.str());
abort_connection_with_unexpected_error(e); abort_connection_with_unexpected_error(e);
} }


strFree(filtered);

return 1; return 1;


case FL_ENTER: case FL_ENTER:

+ 8
- 12
win/rfb_win32/Clipboard.cxx View File

return MsgWindow::processMessage(msg, wParam, lParam); return MsgWindow::processMessage(msg, wParam, lParam);
}; };


char*
std::string
Clipboard::getClipText() { Clipboard::getClipText() {
HGLOBAL cliphandle; HGLOBAL cliphandle;
wchar_t* clipdata; wchar_t* clipdata;
CharArray utf8;
std::string utf8;


// Open the clipboard // Open the clipboard
if (!OpenClipboard(getHandle())) if (!OpenClipboard(getHandle()))
} }


// Convert it to UTF-8 // Convert it to UTF-8
utf8.replaceBuf(utf16ToUTF8(clipdata));
utf8 = utf16ToUTF8(clipdata);


// Release the buffer and close the clipboard // Release the buffer and close the clipboard
GlobalUnlock(cliphandle); GlobalUnlock(cliphandle);
CloseClipboard(); CloseClipboard();


return convertLF(utf8.buf);
return convertLF(utf8.c_str());
} }


void void
throw rdr::SystemException("unable to open Win32 clipboard", GetLastError()); throw rdr::SystemException("unable to open Win32 clipboard", GetLastError());


// - Convert the supplied clipboard text into UTF-16 format with CRLF // - Convert the supplied clipboard text into UTF-16 format with CRLF
CharArray filtered(convertCRLF(text));
wchar_t* utf16;

utf16 = utf8ToUTF16(filtered.buf);
std::string filtered(convertCRLF(text));
std::wstring utf16(utf8ToUTF16(filtered.c_str()));


// - Allocate global memory for the data // - Allocate global memory for the data
clip_handle = ::GlobalAlloc(GMEM_MOVEABLE, (wcslen(utf16) + 1) * 2);
clip_handle = ::GlobalAlloc(GMEM_MOVEABLE, (utf16.size() + 1) * 2);


wchar_t* data = (wchar_t*) GlobalLock(clip_handle); wchar_t* data = (wchar_t*) GlobalLock(clip_handle);
wcscpy(data, utf16);
wcscpy(data, utf16.c_str());
GlobalUnlock(clip_handle); GlobalUnlock(clip_handle);


strFree(utf16);

// - Next, we must clear out any existing data // - Next, we must clear out any existing data
if (!EmptyClipboard()) if (!EmptyClipboard())
throw rdr::SystemException("unable to empty Win32 clipboard", GetLastError()); throw rdr::SystemException("unable to empty Win32 clipboard", GetLastError());

+ 1
- 1
win/rfb_win32/Clipboard.h View File

void setNotifier(Notifier* cbn) {notifier = cbn;} void setNotifier(Notifier* cbn) {notifier = cbn;}


// - Get the clipboard contents // - Get the clipboard contents
char* getClipText();
std::string getClipText();


// - Set the clipboard contents // - Set the clipboard contents
void setClipText(const char* text); void setClipText(const char* text);

+ 2
- 3
win/rfb_win32/RegConfig.cxx View File



#include <rfb_win32/RegConfig.h> #include <rfb_win32/RegConfig.h>
#include <rfb/LogWriter.h> #include <rfb/LogWriter.h>
#include <rfb/util.h>
//#include <rdr/HexOutStream.h> //#include <rdr/HexOutStream.h>


using namespace rfb; using namespace rfb;
while (1) { while (1) {
const char *name = key.getValueName(i++); const char *name = key.getValueName(i++);
if (!name) break; if (!name) break;
CharArray value(key.getRepresentation(name));
if (!value.buf || !Configuration::setParam(name, value.buf))
std::string value = key.getRepresentation(name);
if (!Configuration::setParam(name, value.c_str()))
vlog.info("unable to process %s", name); vlog.info("unable to process %s", name);
} }
} catch (rdr::SystemException& e) { } catch (rdr::SystemException& e) {

+ 22
- 31
win/rfb_win32/Registry.cxx View File

setInt(valname, value ? 1 : 0); setInt(valname, value ? 1 : 0);
} }


char* RegKey::getString(const char* valname) const {return getRepresentation(valname);}
char* RegKey::getString(const char* valname, const char* def) const {
std::string RegKey::getString(const char* valname) const {
return getRepresentation(valname);
}

std::string RegKey::getString(const char* valname, const char* def) const {
try { try {
return getString(valname); return getString(valname);
} catch(rdr::Exception&) { } catch(rdr::Exception&) {
return strDup(def);
return def;
} }
} }


std::vector<uint8_t> RegKey::getBinary(const char* valname) const { std::vector<uint8_t> RegKey::getBinary(const char* valname) const {
CharArray hex(getRepresentation(valname));
return hexToBin(hex.buf, strlen(hex.buf));
std::string hex = getRepresentation(valname);
return hexToBin(hex.data(), hex.size());
} }
std::vector<uint8_t> RegKey::getBinary(const char* valname, const uint8_t* def, size_t deflen) const { std::vector<uint8_t> RegKey::getBinary(const char* valname, const uint8_t* def, size_t deflen) const {
try { try {
} }


int RegKey::getInt(const char* valname) const { int RegKey::getInt(const char* valname) const {
CharArray tmp(getRepresentation(valname));
return atoi(tmp.buf);
return atoi(getRepresentation(valname).c_str());
} }
int RegKey::getInt(const char* valname, int def) const { int RegKey::getInt(const char* valname, int def) const {
try { try {
return getInt(valname, def ? 1 : 0) > 0; return getInt(valname, def ? 1 : 0) > 0;
} }


static inline char* terminateData(char* data, int length)
{
// We must terminate the string, just to be sure. Stupid Win32...
int len = length/sizeof(char);
CharArray str(len+1);
memcpy(str.buf, data, length);
str.buf[len] = 0;
return str.takeBuf();
}

char* RegKey::getRepresentation(const char* valname) const {
std::string RegKey::getRepresentation(const char* valname) const {
DWORD type, length; DWORD type, length;
LONG result = RegQueryValueEx(key, valname, 0, &type, 0, &length); LONG result = RegQueryValueEx(key, valname, 0, &type, 0, &length);
if (result != ERROR_SUCCESS) if (result != ERROR_SUCCESS)
switch (type) { switch (type) {
case REG_BINARY: case REG_BINARY:
{ {
CharArray hex(binToHex((const uint8_t*)data.buf, length));
return hex.takeBuf();
return binToHex((const uint8_t*)data.buf, length);
} }
case REG_SZ: case REG_SZ:
if (length) { if (length) {
return terminateData(data.buf, length);
return std::string(data.buf, length);
} else { } else {
return strDup("");
return "";
} }
case REG_DWORD: case REG_DWORD:
{ {
CharArray tmp(16);
sprintf(tmp.buf, "%lu", *((DWORD*)data.buf));
return tmp.takeBuf();
char tmp[16];
sprintf(tmp, "%lu", *((DWORD*)data.buf));
return tmp;
} }
case REG_EXPAND_SZ: case REG_EXPAND_SZ:
{ {
if (length) { if (length) {
CharArray str(terminateData(data.buf, length));
DWORD required = ExpandEnvironmentStrings(str.buf, 0, 0);
std::string str(data.buf, length);
DWORD required = ExpandEnvironmentStrings(str.c_str(), 0, 0);
if (required==0) if (required==0)
throw rdr::SystemException("ExpandEnvironmentStrings", GetLastError()); throw rdr::SystemException("ExpandEnvironmentStrings", GetLastError());
CharArray result(required); CharArray result(required);
length = ExpandEnvironmentStrings(str.buf, result.buf, required);
length = ExpandEnvironmentStrings(str.c_str(), result.buf, required);
if (required<length) if (required<length)
throw rdr::Exception("unable to expand environment strings"); throw rdr::Exception("unable to expand environment strings");
return result.takeBuf();
return result.buf;
} else { } else {
return strDup("");
return "";
} }
} }
default: default:


bool RegKey::isValue(const char* valname) const { bool RegKey::isValue(const char* valname) const {
try { try {
CharArray tmp(getRepresentation(valname));
getRepresentation(valname);
return true; return true;
} catch(rdr::Exception&) { } catch(rdr::Exception&) {
return false; return false;

+ 3
- 3
win/rfb_win32/Registry.h View File

void setInt(const char* valname, int i) const; void setInt(const char* valname, int i) const;
void setBool(const char* valname, bool b) const; void setBool(const char* valname, bool b) const;


char* getString(const char* valname) const;
char* getString(const char* valname, const char* def) const;
std::string getString(const char* valname) const;
std::string getString(const char* valname, const char* def) const;


std::vector<uint8_t> getBinary(const char* valname) const; std::vector<uint8_t> getBinary(const char* valname) const;
std::vector<uint8_t> getBinary(const char* valname, const uint8_t* def, size_t deflength) const; std::vector<uint8_t> getBinary(const char* valname, const uint8_t* def, size_t deflength) const;
bool getBool(const char* valname) const; bool getBool(const char* valname) const;
bool getBool(const char* valname, bool def) const; bool getBool(const char* valname, bool def) const;


char* getRepresentation(const char* valname) const;
std::string getRepresentation(const char* valname) const;


bool isValue(const char* valname) const; bool isValue(const char* valname) const;



+ 1
- 2
win/rfb_win32/SDisplay.cxx View File





void SDisplay::handleClipboardRequest() { void SDisplay::handleClipboardRequest() {
CharArray data(clipboard->getClipText());
server->sendClipboardData(data.buf);
server->sendClipboardData(clipboard->getClipText().c_str());
} }


void SDisplay::handleClipboardAnnounce(bool available) { void SDisplay::handleClipboardAnnounce(bool available) {

+ 3
- 3
win/rfb_win32/Win32Util.cxx View File

langId = langId >> 8; langId = langId >> 8;
} }


CharArray langIdStr(binToHex(langIdBuf, sizeof(langId)));
CharArray infoName(strlen("StringFileInfo") + 4 + strlen(name) + strlen(langIdStr.buf));
sprintf(infoName.buf, "\\StringFileInfo\\%s\\%s", langIdStr.buf, name);
std::string langIdStr(binToHex(langIdBuf, sizeof(langId)));
CharArray infoName(strlen("StringFileInfo") + 4 + strlen(name) + strlen(langIdStr.c_str()));
sprintf(infoName.buf, "\\StringFileInfo\\%s\\%s", langIdStr.c_str(), name);


// Locate the required version string within the version info // Locate the required version string within the version info
char* buffer = 0; char* buffer = 0;

+ 2
- 2
win/vncconfig/Authentication.h View File



#ifdef HAVE_GNUTLS #ifdef HAVE_GNUTLS
if (isItemChecked(IDC_ENC_X509)) { if (isItemChecked(IDC_ENC_X509)) {
SSecurityTLS::X509_CertFile.setParam(regKey.getString("X509Cert"));
SSecurityTLS::X509_CertFile.setParam(regKey.getString("X509Key"));
SSecurityTLS::X509_CertFile.setParam(regKey.getString("X509Cert").c_str());
SSecurityTLS::X509_CertFile.setParam(regKey.getString("X509Key").c_str());
} }
#endif #endif



+ 10
- 10
win/vncconfig/Connections.h View File



try { try {
network::TcpFilter::Pattern pat(network::TcpFilter::parsePattern(newPat.buf)); network::TcpFilter::Pattern pat(network::TcpFilter::parsePattern(newPat.buf));
pattern.replaceBuf(CharArray(network::TcpFilter::patternToStr(pat)).takeBuf());
pattern.replaceBuf(strDup(network::TcpFilter::patternToStr(pat).c_str()));
} catch(rdr::Exception& e) { } catch(rdr::Exception& e) {
MsgBox(NULL, e.str(), MB_ICONEXCLAMATION | MB_OK); MsgBox(NULL, e.str(), MB_ICONEXCLAMATION | MB_OK);
return false; return false;
SendMessage(listBox, LB_DELETESTRING, 0, 0); SendMessage(listBox, LB_DELETESTRING, 0, 0);


CharArray tmp; CharArray tmp;
tmp.buf = hosts.getData();
tmp.buf = strDup(hosts.getValueStr().c_str());
while (tmp.buf) { while (tmp.buf) {
CharArray first; CharArray first;
strSplit(tmp.buf, ',', &first.buf, &tmp.buf); strSplit(tmp.buf, ',', &first.buf, &tmp.buf);
regKey.setInt("PortNumber", isItemChecked(IDC_RFB_ENABLE) ? getItemInt(IDC_PORT) : 0); regKey.setInt("PortNumber", isItemChecked(IDC_RFB_ENABLE) ? getItemInt(IDC_PORT) : 0);
regKey.setInt("IdleTimeout", getItemInt(IDC_IDLE_TIMEOUT)); regKey.setInt("IdleTimeout", getItemInt(IDC_IDLE_TIMEOUT));
regKey.setInt("LocalHost", isItemChecked(IDC_LOCALHOST)); regKey.setInt("LocalHost", isItemChecked(IDC_LOCALHOST));
regKey.setString("Hosts", CharArray(getHosts()).buf);
regKey.setString("Hosts", getHosts().c_str());
return true; return true;
} }
bool isChanged() { bool isChanged() {
try { try {
CharArray new_hosts(getHosts());
return (strcmp(new_hosts.buf, hosts) != 0) ||
std::string new_hosts = getHosts();
return (new_hosts != (const char*)hosts) ||
(localHost != isItemChecked(IDC_LOCALHOST)) || (localHost != isItemChecked(IDC_LOCALHOST)) ||
(port_number != getItemInt(IDC_PORT)) || (port_number != getItemInt(IDC_PORT)) ||
(rfb::Server::idleTimeout != getItemInt(IDC_IDLE_TIMEOUT)); (rfb::Server::idleTimeout != getItemInt(IDC_IDLE_TIMEOUT));
return false; return false;
} }
} }
char* getHosts() {
std::string getHosts() {
int bufLen = 1, i; int bufLen = 1, i;
HWND listBox = GetDlgItem(handle, IDC_HOSTS); HWND listBox = GetDlgItem(handle, IDC_HOSTS);
for (i=0; i<SendMessage(listBox, LB_GETCOUNT, 0, 0); i++) for (i=0; i<SendMessage(listBox, LB_GETCOUNT, 0, 0); i++)
bufLen+=SendMessage(listBox, LB_GETTEXTLEN, i, 0)+1; bufLen+=SendMessage(listBox, LB_GETTEXTLEN, i, 0)+1;
CharArray hosts_str(bufLen);
hosts_str.buf[0] = 0;
char* outPos = hosts_str.buf;
std::vector<char> hosts_str(bufLen);
hosts_str[0] = 0;
char* outPos = hosts_str.data();
for (i=0; i<SendMessage(listBox, LB_GETCOUNT, 0, 0); i++) { for (i=0; i<SendMessage(listBox, LB_GETCOUNT, 0, 0); i++) {
outPos += SendMessage(listBox, LB_GETTEXT, i, (LPARAM)outPos); outPos += SendMessage(listBox, LB_GETTEXT, i, (LPARAM)outPos);
outPos[0] = ','; outPos[0] = ',';
outPos[1] = 0; outPos[1] = 0;
outPos++; outPos++;
} }
return strDup(hosts_str.buf);
return hosts_str.data();
} }


protected: protected:

+ 3
- 4
win/vncconfig/Legacy.cxx View File

regKey.setString("Log", logSetting); regKey.setString("Log", logSetting);
} }
CharArray authHosts;
authHosts.buf = winvnc3.getString("AuthHosts", 0);
if (authHosts.buf) {
std::string authHosts = winvnc3.getString("AuthHosts", "");
if (!authHosts.empty()) {
CharArray newHosts; CharArray newHosts;
newHosts.buf = strDup(""); newHosts.buf = strDup("");


// Reformat AuthHosts to Hosts. Wish I'd left the format the same. :( :( :( // Reformat AuthHosts to Hosts. Wish I'd left the format the same. :( :( :(
try { try {
CharArray tmp(authHosts.buf);
CharArray tmp(strDup(authHosts.c_str()));
while (tmp.buf) { while (tmp.buf) {


// Split the AuthHosts string into patterns to match // Split the AuthHosts string into patterns to match

+ 9
- 10
win/winvnc/VNCServerWin32.cxx View File

prefix = "VNC Server (Service):"; prefix = "VNC Server (Service):";


// Fetch the list of addresses // Fetch the list of addresses
std::list<char*> addrs;
std::list<std::string> addrs;
if (rfbSock.isListening()) if (rfbSock.isListening())
TcpListener::getMyAddresses(&addrs);
addrs = TcpListener::getMyAddresses();
else else
addrs.push_front(strDup("Not accepting connections"));
addrs.push_front("Not accepting connections");


// Allocate space for the new tip // Allocate space for the new tip
std::list<char*>::iterator i, next_i;
std::list<std::string>::iterator i, next_i;
int length = strlen(prefix)+1; int length = strlen(prefix)+1;
for (i=addrs.begin(); i!= addrs.end(); i++) for (i=addrs.begin(); i!= addrs.end(); i++)
length += strlen(*i) + 1;
length += i->size() + 1;


// Build the new tip // Build the new tip
CharArray toolTip(length); CharArray toolTip(length);
strcpy(toolTip.buf, prefix); strcpy(toolTip.buf, prefix);
for (i=addrs.begin(); i!= addrs.end(); i=next_i) { for (i=addrs.begin(); i!= addrs.end(); i=next_i) {
next_i = i; next_i ++; next_i = i; next_i ++;
CharArray addr(*i); // Assumes ownership of string
strcat(toolTip.buf, addr.buf);
strcat(toolTip.buf, i->c_str());
if (next_i != addrs.end()) if (next_i != addrs.end())
strcat(toolTip.buf, ","); strcat(toolTip.buf, ",");
} }
bool VNCServerWin32::addNewClient(const char* client) { bool VNCServerWin32::addNewClient(const char* client) {
TcpSocket* sock = 0; TcpSocket* sock = 0;
try { try {
CharArray hostname;
std::string hostname;
int port; int port;
getHostAndPort(client, &hostname.buf, &port, 5500);
getHostAndPort(client, &hostname, &port, 5500);
vlog.error("port=%d", port); vlog.error("port=%d", port);
sock = new TcpSocket(hostname.buf, port);
sock = new TcpSocket(hostname.c_str(), port);
if (queueCommand(AddClient, sock, 0)) if (queueCommand(AddClient, sock, 0))
return true; return true;
delete sock; delete sock;

Loading…
Cancel
Save