vlog.error("cut text too long (%d bytes) - ignoring",len);
return;
}
- CharArray ca(len+1);
- ca.buf[len] = 0;
+ CharArray ca(len);
is->readBytes(ca.buf, len);
- handler->serverCutText(ca.buf, len);
+ CharArray filtered(convertLF(ca.buf, len));
+ handler->serverCutText(filtered.buf, strlen(filtered.buf));
}
void CMsgReader::readFence()
void CMsgWriter::writeClientCutText(const char* str, rdr::U32 len)
{
+ if (memchr(str, '\r', len) != NULL)
+ throw Exception("Invalid carriage return in clipboard data");
+
startMsg(msgTypeClientCutText);
os->pad(3);
os->writeU32(len);
vlog.error("Cut text too long (%d bytes) - ignoring", len);
return;
}
- CharArray ca(len+1);
- ca.buf[len] = 0;
+ CharArray ca(len);
is->readBytes(ca.buf, len);
- handler->clientCutText(ca.buf, len);
+ CharArray filtered(convertLF(ca.buf, len));
+ handler->clientCutText(filtered.buf, strlen(filtered.buf));
}
void SMsgReader::readQEMUMessage()
void SMsgWriter::writeServerCutText(const char* str, int len)
{
+ if (memchr(str, '\r', len) != NULL)
+ throw Exception("Invalid carriage return in clipboard data");
+
startMsg(msgTypeServerCutText);
os->pad(3);
os->writeU32(len);
void VNCServerST::serverCutText(const char* str, int len)
{
+ if (memchr(str, '\r', len) != NULL)
+ throw Exception("Invalid carriage return in clipboard data");
std::list<VNCSConnectionST*>::iterator ci, ci_next;
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
ci_next = ci; ci_next++;
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2011-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
dest[src ? destlen-1 : 0] = 0;
}
+ char* convertLF(const char* src, size_t bytes)
+ {
+ char* buffer;
+ size_t sz;
+
+ char* out;
+ const char* in;
+ size_t in_len;
+
+ // Always include space for a NULL
+ sz = 1;
+
+ // Compute output size
+ in = src;
+ in_len = bytes;
+ while ((*in != '\0') && (in_len > 0)) {
+ if (*in != '\r') {
+ sz++;
+ in++;
+ in_len--;
+ continue;
+ }
+
+ if ((in_len == 0) || (*(in+1) != '\n'))
+ sz++;
+
+ in++;
+ in_len--;
+ }
+
+ // Alloc
+ buffer = new char[sz];
+ memset(buffer, 0, sz);
+
+ // And convert
+ out = buffer;
+ in = src;
+ in_len = bytes;
+ while ((*in != '\0') && (in_len > 0)) {
+ if (*in != '\r') {
+ *out++ = *in++;
+ in_len--;
+ continue;
+ }
+
+ if ((in_len == 0) || (*(in+1) != '\n'))
+ *out++ = '\n';
+
+ in++;
+ in_len--;
+ }
+
+ return buffer;
+ }
+
unsigned msBetween(const struct timeval *first,
const struct timeval *second)
{
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2011-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
// Copies src to dest, up to specified length-1, and guarantees termination
void strCopy(char* dest, const char* src, int destlen);
+ // Makes sure line endings are in a certain format
+
+ char* convertLF(const char* src, size_t bytes = (size_t)-1);
// HELPER functions for timeout handling
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2011-2015 Pierre Ossman for Cendio AB
+ * Copyright 2011-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
}
return 0;
}
+
+char* vncConvertLF(const char* src, size_t bytes)
+{
+ try {
+ return convertLF(src, bytes);
+ } catch (...) {
+ return NULL;
+ }
+}
+
+void vncStrFree(char* str)
+{
+ strFree(str);
+}
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2011-2015 Pierre Ossman for Cendio AB
+ * Copyright 2011-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
int vncGetSocketPort(int fd);
int vncIsTCPPortUsed(int port);
+char* vncConvertLF(const char* src, size_t bytes);
+void vncStrFree(char* str);
+
#ifdef __cplusplus
}
#endif
-/* Copyright 2016 Pierre Ossman for Cendio AB
+/* Copyright 2016-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
else if (vncHasAtom(xaUTF8_STRING, (const Atom*)prop->data, prop->size))
vncSelectionRequest(selection, xaUTF8_STRING);
} else if (target == xaSTRING) {
+ char* filtered;
+
if (prop->format != 8)
return;
if (prop->type != xaSTRING)
return;
- vncServerCutText(prop->data, prop->size);
+ filtered = vncConvertLF(prop->data, prop->size);
+ if (filtered == NULL)
+ return;
+
+ vncServerCutText(filtered, strlen(filtered));
+
+ vncStrFree(filtered);
} else if (target == xaUTF8_STRING) {
+ char *filtered;
unsigned char* buffer;
unsigned char* out;
size_t len;
}
}
- vncServerCutText((const char*)buffer, len);
-
+ filtered = vncConvertLF(buffer, len);
free(buffer);
+ if (filtered == NULL)
+ return;
+
+ vncServerCutText(filtered, strlen(filtered));
+
+ vncStrFree(filtered);
}
}
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2011-2014 Pierre Ossman for Cendio AB
+ * Copyright 2011-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
int Viewport::handle(int event)
{
- char *buffer;
+ char *buffer, *filtered;
int ret;
int buttonMask, wheelMask;
DownMap::const_iterator iter;
ret = fl_utf8toa(Fl::event_text(), Fl::event_length(), buffer,
Fl::event_length() + 1);
assert(ret < (Fl::event_length() + 1));
+ filtered = convertLF(buffer, ret);
+ delete [] buffer;
if (!hasFocus()) {
- pendingClientCutText = buffer;
+ pendingClientCutText = new char[strlen(filtered) + 1];
+ strcpy((char*)pendingClientCutText, filtered);
+ strFree(filtered);
return 1;
}
- vlog.debug("Sending clipboard data (%d bytes)", (int)strlen(buffer));
+ vlog.debug("Sending clipboard data (%d bytes)", (int)strlen(filtered));
try {
- cc->writer()->writeClientCutText(buffer, ret);
+ cc->writer()->writeClientCutText(filtered, strlen(filtered));
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(e.str());
}
- delete [] buffer;
+ strFree(filtered);
return 1;
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2012-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
// -=- CR/LF handlers
//
-char*
-dos2unix(const char* text) {
- int len = strlen(text)+1;
- char* unix = new char[strlen(text)+1];
- int i, j=0;
- for (i=0; i<len; i++) {
- if (text[i] != '\x0d')
- unix[j++] = text[i];
- }
- return unix;
-}
-
char*
unix2dos(const char* text) {
int len = strlen(text)+1;
if (!clipdata) {
notifier->notifyClipboardChanged(0, 0);
} else {
- CharArray unix_text;
- unix_text.buf = dos2unix(clipdata);
+ CharArray unix_text(convertLF(clipdata, strlen(clipdata)));
removeNonISOLatin1Chars(unix_text.buf);
notifier->notifyClipboardChanged(unix_text.buf, strlen(unix_text.buf));
}