Clean up internal clipboard handling

We now filter incoming data, which means we can start assuming the
clipboard data is always null terminated. This allows us to clean
up a lot of the internal handling.
diff --git a/common/rfb/CMsgHandler.h b/common/rfb/CMsgHandler.h
index effdaab..1581f79 100644
--- a/common/rfb/CMsgHandler.h
+++ b/common/rfb/CMsgHandler.h
@@ -70,7 +70,7 @@
     virtual void setColourMapEntries(int firstColour, int nColours,
 				     rdr::U16* rgbs) = 0;
     virtual void bell() = 0;
-    virtual void serverCutText(const char* str, rdr::U32 len) = 0;
+    virtual void serverCutText(const char* str) = 0;
 
     virtual void setLEDState(unsigned int state);
 
diff --git a/common/rfb/CMsgReader.cxx b/common/rfb/CMsgReader.cxx
index a928eb1..86288ad 100644
--- a/common/rfb/CMsgReader.cxx
+++ b/common/rfb/CMsgReader.cxx
@@ -160,7 +160,7 @@
   CharArray ca(len);
   is->readBytes(ca.buf, len);
   CharArray filtered(convertLF(ca.buf, len));
-  handler->serverCutText(filtered.buf, strlen(filtered.buf));
+  handler->serverCutText(filtered.buf);
 }
 
 void CMsgReader::readFence()
diff --git a/common/rfb/CMsgWriter.cxx b/common/rfb/CMsgWriter.cxx
index fed0bd2..f1fa58d 100644
--- a/common/rfb/CMsgWriter.cxx
+++ b/common/rfb/CMsgWriter.cxx
@@ -179,11 +179,14 @@
 }
 
 
-void CMsgWriter::writeClientCutText(const char* str, rdr::U32 len)
+void CMsgWriter::writeClientCutText(const char* str)
 {
-  if (memchr(str, '\r', len) != NULL)
+  size_t len;
+
+  if (strchr(str, '\r') != NULL)
     throw Exception("Invalid carriage return in clipboard data");
 
+  len = strlen(str);
   startMsg(msgTypeClientCutText);
   os->pad(3);
   os->writeU32(len);
diff --git a/common/rfb/CMsgWriter.h b/common/rfb/CMsgWriter.h
index 4d533d4..d3ac19c 100644
--- a/common/rfb/CMsgWriter.h
+++ b/common/rfb/CMsgWriter.h
@@ -55,7 +55,7 @@
 
     void writeKeyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
     void writePointerEvent(const Point& pos, int buttonMask);
-    void writeClientCutText(const char* str, rdr::U32 len);
+    void writeClientCutText(const char* str);
 
   protected:
     void startMsg(int type);
diff --git a/common/rfb/InputHandler.h b/common/rfb/InputHandler.h
index 6c07284..b91f0e4 100644
--- a/common/rfb/InputHandler.h
+++ b/common/rfb/InputHandler.h
@@ -37,8 +37,7 @@
                           bool __unused_attr down) { }
     virtual void pointerEvent(const Point& __unused_attr pos,
                               int __unused_attr buttonMask) { }
-    virtual void clientCutText(const char* __unused_attr str,
-                               int __unused_attr len) { }
+    virtual void clientCutText(const char* __unused_attr str) { }
   };
 
 }
diff --git a/common/rfb/SMsgReader.cxx b/common/rfb/SMsgReader.cxx
index 0c0e8b2..5efbfe2 100644
--- a/common/rfb/SMsgReader.cxx
+++ b/common/rfb/SMsgReader.cxx
@@ -215,7 +215,7 @@
   CharArray ca(len);
   is->readBytes(ca.buf, len);
   CharArray filtered(convertLF(ca.buf, len));
-  handler->clientCutText(filtered.buf, strlen(filtered.buf));
+  handler->clientCutText(filtered.buf);
 }
 
 void SMsgReader::readQEMUMessage()
diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx
index f0748ff..3d5a64c 100644
--- a/common/rfb/SMsgWriter.cxx
+++ b/common/rfb/SMsgWriter.cxx
@@ -78,11 +78,14 @@
   endMsg();
 }
 
-void SMsgWriter::writeServerCutText(const char* str, int len)
+void SMsgWriter::writeServerCutText(const char* str)
 {
-  if (memchr(str, '\r', len) != NULL)
+  size_t len;
+
+  if (strchr(str, '\r') != NULL)
     throw Exception("Invalid carriage return in clipboard data");
 
+  len = strlen(str);
   startMsg(msgTypeServerCutText);
   os->pad(3);
   os->writeU32(len);
diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h
index 4f4c9cc..8cf2ae7 100644
--- a/common/rfb/SMsgWriter.h
+++ b/common/rfb/SMsgWriter.h
@@ -56,7 +56,7 @@
 
     // writeBell() and writeServerCutText() do the obvious thing.
     void writeBell();
-    void writeServerCutText(const char* str, int len);
+    void writeServerCutText(const char* str);
 
     // writeFence() sends a new fence request or response to the client.
     void writeFence(rdr::U32 flags, unsigned len, const char data[]);
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index fe00dab..002ae92 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -282,13 +282,13 @@
   }
 }
 
-void VNCSConnectionST::serverCutTextOrClose(const char *str, int len)
+void VNCSConnectionST::serverCutTextOrClose(const char *str)
 {
   try {
     if (!accessCheck(AccessCutText)) return;
     if (!rfb::Server::sendCutText) return;
     if (state() == RFBSTATE_NORMAL)
-      writer()->writeServerCutText(str, len);
+      writer()->writeServerCutText(str);
   } catch(rdr::Exception& e) {
     close(e.str());
   }
@@ -596,11 +596,11 @@
   server->keyEvent(keysym, keycode, down);
 }
 
-void VNCSConnectionST::clientCutText(const char* str, int len)
+void VNCSConnectionST::clientCutText(const char* str)
 {
   if (!accessCheck(AccessCutText)) return;
   if (!rfb::Server::acceptCutText) return;
-  server->clientCutText(str, len);
+  server->clientCutText(str);
 }
 
 void VNCSConnectionST::framebufferUpdateRequest(const Rect& r,bool incremental)
diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
index a9a8d3a..54266e3 100644
--- a/common/rfb/VNCSConnectionST.h
+++ b/common/rfb/VNCSConnectionST.h
@@ -72,7 +72,7 @@
     void screenLayoutChangeOrClose(rdr::U16 reason);
     void setCursorOrClose();
     void bellOrClose();
-    void serverCutTextOrClose(const char *str, int len);
+    void serverCutTextOrClose(const char *str);
     void setDesktopNameOrClose(const char *name);
     void setLEDStateOrClose(unsigned int state);
     void approveConnectionOrClose(bool accept, const char* reason);
@@ -115,7 +115,7 @@
     virtual void setPixelFormat(const PixelFormat& pf);
     virtual void pointerEvent(const Point& pos, int buttonMask);
     virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
-    virtual void clientCutText(const char* str, int len);
+    virtual void clientCutText(const char* str);
     virtual void framebufferUpdateRequest(const Rect& r, bool incremental);
     virtual void setDesktopSize(int fb_width, int fb_height,
                                 const ScreenSet& layout);
diff --git a/common/rfb/VNCServer.h b/common/rfb/VNCServer.h
index 298326f..5398e9f 100644
--- a/common/rfb/VNCServer.h
+++ b/common/rfb/VNCServer.h
@@ -57,7 +57,7 @@
 
     // serverCutText() tells the server that the cut text has changed.  This
     // will normally be sent to all clients.
-    virtual void serverCutText(const char* str, int len) = 0;
+    virtual void serverCutText(const char* str) = 0;
 
     // bell() tells the server that it should make all clients make a bell sound.
     virtual void bell() = 0;
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 7820aef..21af0da 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -340,14 +340,14 @@
   }
 }
 
-void VNCServerST::serverCutText(const char* str, int len)
+void VNCServerST::serverCutText(const char* str)
 {
-  if (memchr(str, '\r', len) != NULL)
+  if (strchr(str, '\r') != 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++;
-    (*ci)->serverCutTextOrClose(str, len);
+    (*ci)->serverCutTextOrClose(str);
   }
 }
 
@@ -461,9 +461,9 @@
   desktop->pointerEvent(pos, buttonMask);
 }
 
-void VNCServerST::clientCutText(const char* str, int len)
+void VNCServerST::clientCutText(const char* str)
 {
-  desktop->clientCutText(str, len);
+  desktop->clientCutText(str);
 }
 
 unsigned int VNCServerST::setDesktopSize(VNCSConnectionST* requester,
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
index 43a3bb9..5231977 100644
--- a/common/rfb/VNCServerST.h
+++ b/common/rfb/VNCServerST.h
@@ -85,7 +85,7 @@
     virtual void setPixelBuffer(PixelBuffer* pb);
     virtual void setScreenLayout(const ScreenSet& layout);
     virtual const PixelBuffer* getPixelBuffer() const { return pb; }
-    virtual void serverCutText(const char* str, int len);
+    virtual void serverCutText(const char* str);
 
     virtual void approveConnection(network::Socket* sock, bool accept,
                                    const char* reason);
@@ -115,7 +115,7 @@
     // Event handlers
     void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
     void pointerEvent(VNCSConnectionST* client, const Point& pos, int buttonMask);
-    void clientCutText(const char* str, int len);
+    void clientCutText(const char* str);
 
     unsigned int setDesktopSize(VNCSConnectionST* requester,
                                 int fb_width, int fb_height,
diff --git a/tests/decperf.cxx b/tests/decperf.cxx
index 301e45e..df5214f 100644
--- a/tests/decperf.cxx
+++ b/tests/decperf.cxx
@@ -54,7 +54,7 @@
   virtual void framebufferUpdateEnd();
   virtual void setColourMapEntries(int, int, rdr::U16*);
   virtual void bell();
-  virtual void serverCutText(const char*, rdr::U32);
+  virtual void serverCutText(const char*);
 
 public:
   double cpuTime;
@@ -122,7 +122,7 @@
 {
 }
 
-void CConn::serverCutText(const char*, rdr::U32)
+void CConn::serverCutText(const char*)
 {
 }
 
diff --git a/tests/encperf.cxx b/tests/encperf.cxx
index 6523eb7..e461197 100644
--- a/tests/encperf.cxx
+++ b/tests/encperf.cxx
@@ -96,7 +96,7 @@
   virtual void dataRect(const rfb::Rect&, int);
   virtual void setColourMapEntries(int, int, rdr::U16*);
   virtual void bell();
-  virtual void serverCutText(const char*, rdr::U32);
+  virtual void serverCutText(const char*);
 
 public:
   double decodeTime;
@@ -254,7 +254,7 @@
 {
 }
 
-void CConn::serverCutText(const char*, rdr::U32)
+void CConn::serverCutText(const char*)
 {
 }
 
diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx
index 564b2d5..8be9aa3 100644
--- a/unix/x0vncserver/XDesktop.cxx
+++ b/unix/x0vncserver/XDesktop.cxx
@@ -406,7 +406,7 @@
 #endif
 }
 
-void XDesktop::clientCutText(const char* str, int len) {
+void XDesktop::clientCutText(const char* str) {
 }
 
 ScreenSet XDesktop::computeScreenLayout()
diff --git a/unix/x0vncserver/XDesktop.h b/unix/x0vncserver/XDesktop.h
index 3e85aac..840d433 100644
--- a/unix/x0vncserver/XDesktop.h
+++ b/unix/x0vncserver/XDesktop.h
@@ -56,7 +56,7 @@
   virtual void pointerEvent(const rfb::Point& pos, int buttonMask);
   KeyCode XkbKeysymToKeycode(Display* dpy, KeySym keysym);
   virtual void keyEvent(rdr::U32 keysym, rdr::U32 xtcode, bool down);
-  virtual void clientCutText(const char* str, int len);
+  virtual void clientCutText(const char* str);
   virtual unsigned int setScreenLayout(int fb_width, int fb_height,
                                        const rfb::ScreenSet& layout);
 
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc
index d8b3a4d..cd9b1f9 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
@@ -192,10 +192,10 @@
   server->setLEDState(state);
 }
 
-void XserverDesktop::serverCutText(const char* str, int len)
+void XserverDesktop::serverCutText(const char* str)
 {
   try {
-    server->serverCutText(str, len);
+    server->serverCutText(str);
   } catch (rdr::Exception& e) {
     vlog.error("XserverDesktop::serverCutText: %s",e.str());
   }
@@ -436,9 +436,9 @@
   vncPointerButtonAction(buttonMask);
 }
 
-void XserverDesktop::clientCutText(const char* str, int len)
+void XserverDesktop::clientCutText(const char* str)
 {
-  vncClientCutText(str, len);
+  vncClientCutText(str);
 }
 
 unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height,
diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h
index 1253935..c6c4eb1 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.h
+++ b/unix/xserver/hw/vnc/XserverDesktop.h
@@ -61,7 +61,7 @@
   void refreshScreenLayout();
   void bell();
   void setLEDState(unsigned int state);
-  void serverCutText(const char* str, int len);
+  void serverCutText(const char* str);
   void setDesktopName(const char* name);
   void setCursor(int width, int height, int hotX, int hotY,
                  const unsigned char *rgbaData);
@@ -92,7 +92,7 @@
                                const char* userName);
   virtual void pointerEvent(const rfb::Point& pos, int buttonMask);
   virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
-  virtual void clientCutText(const char* str, int len);
+  virtual void clientCutText(const char* str);
   virtual unsigned int setScreenLayout(int fb_width, int fb_height,
                                        const rfb::ScreenSet& layout);
 
diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc
index 20072f4..10143f6 100644
--- a/unix/xserver/hw/vnc/vncExtInit.cc
+++ b/unix/xserver/hw/vnc/vncExtInit.cc
@@ -285,10 +285,10 @@
     desktop[scr]->setDesktopName(desktopName);
 }
 
-void vncServerCutText(const char *text, size_t len)
+void vncServerCutText(const char *text)
 {
   for (int scr = 0; scr < vncGetScreenCount(); scr++)
-    desktop[scr]->serverCutText(text, len);
+    desktop[scr]->serverCutText(text);
 }
 
 int vncConnectClient(const char *addr)
diff --git a/unix/xserver/hw/vnc/vncExtInit.h b/unix/xserver/hw/vnc/vncExtInit.h
index 5f97f96..bdcce83 100644
--- a/unix/xserver/hw/vnc/vncExtInit.h
+++ b/unix/xserver/hw/vnc/vncExtInit.h
@@ -53,7 +53,7 @@
 
 void vncUpdateDesktopName(void);
 
-void vncServerCutText(const char *text, size_t len);
+void vncServerCutText(const char *text);
 
 int vncConnectClient(const char *addr);
 
diff --git a/unix/xserver/hw/vnc/vncSelection.c b/unix/xserver/hw/vnc/vncSelection.c
index 5ddcaf0..8f4146d 100644
--- a/unix/xserver/hw/vnc/vncSelection.c
+++ b/unix/xserver/hw/vnc/vncSelection.c
@@ -48,7 +48,6 @@
 static Window wid;
 
 static char* clientCutText;
-static int clientCutTextLen;
 
 static int vncCreateSelectionWindow(void);
 static int vncOwnSelection(Atom selection);
@@ -82,23 +81,20 @@
     FatalError("Add VNC SelectionCallback failed\n");
 }
 
-void vncClientCutText(const char* str, int len)
+void vncClientCutText(const char* str)
 {
   int rc;
 
   if (clientCutText != NULL)
     free(clientCutText);
 
-  clientCutText = malloc(len);
+  clientCutText = strdup(str);
   if (clientCutText == NULL) {
     LOG_ERROR("Could not allocate clipboard buffer");
     DeleteWindowFromAnySelections(pWindow);
     return;
   }
 
-  memcpy(clientCutText, str, len);
-  clientCutTextLen = len;
-
   if (vncGetSetPrimary()) {
     rc = vncOwnSelection(xaPRIMARY);
     if (rc != Success)
@@ -246,7 +242,7 @@
   } else if ((target == xaSTRING) || (target == xaTEXT)) {
     rc = dixChangeWindowProperty(serverClient, pWin, realProperty,
                                  XA_STRING, 8, PropModeReplace,
-                                 clientCutTextLen, clientCutText,
+                                 strlen(clientCutText), clientCutText,
                                  TRUE);
     if (rc != Success)
       return rc;
@@ -258,25 +254,22 @@
     const unsigned char* in;
     size_t in_len;
 
-    buffer = malloc(clientCutTextLen*2);
+    buffer = malloc(strlen(clientCutText)*2);
     if (buffer == NULL)
       return BadAlloc;
 
     out = buffer;
     len = 0;
     in = clientCutText;
-    in_len = clientCutTextLen;
-    while (in_len > 0) {
+    while (*in != '\0') {
       if (*in & 0x80) {
         *out++ = 0xc0 | (*in >> 6);
         *out++ = 0x80 | (*in & 0x3f);
         len += 2;
         in++;
-        in_len--;
       } else {
         *out++ = *in++;
         len++;
-        in_len--;
       }
     }
 
@@ -426,7 +419,7 @@
     if (filtered == NULL)
       return;
 
-    vncServerCutText(filtered, strlen(filtered));
+    vncServerCutText(filtered);
 
     vncStrFree(filtered);
   } else if (target == xaUTF8_STRING) {
@@ -484,7 +477,7 @@
     if (filtered == NULL)
       return;
 
-    vncServerCutText(filtered, strlen(filtered));
+    vncServerCutText(filtered);
 
     vncStrFree(filtered);
   }
diff --git a/unix/xserver/hw/vnc/vncSelection.h b/unix/xserver/hw/vnc/vncSelection.h
index 969f895..e11d4a4 100644
--- a/unix/xserver/hw/vnc/vncSelection.h
+++ b/unix/xserver/hw/vnc/vncSelection.h
@@ -1,4 +1,4 @@
-/* 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
@@ -24,7 +24,7 @@
 
 void vncSelectionInit(void);
 
-void vncClientCutText(const char* str, int len);
+void vncClientCutText(const char* str);
 
 #ifdef __cplusplus
 }
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx
index b4610e6..2cc1fe4 100644
--- a/vncviewer/CConn.cxx
+++ b/vncviewer/CConn.cxx
@@ -377,9 +377,9 @@
   fl_beep();
 }
 
-void CConn::serverCutText(const char* str, rdr::U32 len)
+void CConn::serverCutText(const char* str)
 {
-  desktop->serverCutText(str, len);
+  desktop->serverCutText(str);
 }
 
 void CConn::dataRect(const Rect& r, int encoding)
diff --git a/vncviewer/CConn.h b/vncviewer/CConn.h
index 2e3362c..38e09c2 100644
--- a/vncviewer/CConn.h
+++ b/vncviewer/CConn.h
@@ -61,7 +61,7 @@
 
   void bell();
 
-  void serverCutText(const char* str, rdr::U32 len);
+  void serverCutText(const char* str);
 
   void framebufferUpdateStart();
   void framebufferUpdateEnd();
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
index 150c39b..4429e77 100644
--- a/vncviewer/DesktopWindow.cxx
+++ b/vncviewer/DesktopWindow.cxx
@@ -276,9 +276,9 @@
 }
 
 
-void DesktopWindow::serverCutText(const char* str, rdr::U32 len)
+void DesktopWindow::serverCutText(const char* str)
 {
-  viewport->serverCutText(str, len);
+  viewport->serverCutText(str);
 }
 
 
diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h
index 6ec8e1b..fe938d9 100644
--- a/vncviewer/DesktopWindow.h
+++ b/vncviewer/DesktopWindow.h
@@ -63,7 +63,7 @@
   void resizeFramebuffer(int new_w, int new_h);
 
   // Incoming clipboard from server
-  void serverCutText(const char* str, rdr::U32 len);
+  void serverCutText(const char* str);
 
   // New image for the locally rendered cursor
   void setCursor(int width, int height, const rfb::Point& hotspot,
diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx
index 15a3ec4..5e49599 100644
--- a/vncviewer/Viewport.cxx
+++ b/vncviewer/Viewport.cxx
@@ -232,7 +232,7 @@
   damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height());
 }
 
-void Viewport::serverCutText(const char* str, rdr::U32 len)
+void Viewport::serverCutText(const char* str)
 {
   char *buffer;
   int size, ret;
@@ -242,7 +242,7 @@
   if (!acceptClipboard)
     return;
 
-  size = fl_utf8froma(NULL, 0, str, len);
+  size = fl_utf8froma(NULL, 0, str, strlen(str));
   if (size <= 0)
     return;
 
@@ -250,7 +250,7 @@
 
   buffer = new char[size];
 
-  ret = fl_utf8froma(buffer, size, str, len);
+  ret = fl_utf8froma(buffer, size, str, strlen(str));
   assert(ret < size);
 
   vlog.debug("Got clipboard data (%d bytes)", (int)strlen(buffer));
@@ -577,7 +577,7 @@
     vlog.debug("Sending clipboard data (%d bytes)", (int)strlen(filtered));
 
     try {
-      cc->writer()->writeClientCutText(filtered, strlen(filtered));
+      cc->writer()->writeClientCutText(filtered);
     } catch (rdr::Exception& e) {
       vlog.error("%s", e.str());
       exit_vncviewer(e.str());
@@ -768,7 +768,7 @@
     size_t len = strlen(pendingClientCutText);
     vlog.debug("Sending pending clipboard data (%d bytes)", (int)len);
     try {
-      cc->writer()->writeClientCutText(pendingClientCutText, len);
+      cc->writer()->writeClientCutText(pendingClientCutText);
     } catch (rdr::Exception& e) {
       vlog.error("%s", e.str());
       exit_vncviewer(e.str());
diff --git a/vncviewer/Viewport.h b/vncviewer/Viewport.h
index be2192b..c2c9872 100644
--- a/vncviewer/Viewport.h
+++ b/vncviewer/Viewport.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright 2011-2019 Pierre Ossman <ossman@cendio.se> 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
@@ -46,7 +46,7 @@
   void updateWindow();
 
   // Incoming clipboard from server
-  void serverCutText(const char* str, rdr::U32 len);
+  void serverCutText(const char* str);
 
   // New image for the locally rendered cursor
   void setCursor(int width, int height, const rfb::Point& hotspot,
diff --git a/win/rfb_win32/Clipboard.cxx b/win/rfb_win32/Clipboard.cxx
index fca6c1d..4952695 100644
--- a/win/rfb_win32/Clipboard.cxx
+++ b/win/rfb_win32/Clipboard.cxx
@@ -113,11 +113,11 @@
             // Notify clients
             if (notifier) {
               if (!clipdata) {
-                notifier->notifyClipboardChanged(0, 0);
+                notifier->notifyClipboardChanged(0);
               } else {
                 CharArray unix_text(convertLF(clipdata, strlen(clipdata)));
                 removeNonISOLatin1Chars(unix_text.buf);
-                notifier->notifyClipboardChanged(unix_text.buf, strlen(unix_text.buf));
+                notifier->notifyClipboardChanged(unix_text.buf);
               }
             } else {
               vlog.debug("no clipboard notifier registered");
diff --git a/win/rfb_win32/Clipboard.h b/win/rfb_win32/Clipboard.h
index 3da7bfc..c69e981 100644
--- a/win/rfb_win32/Clipboard.h
+++ b/win/rfb_win32/Clipboard.h
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * 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
@@ -38,7 +39,7 @@
       // -=- Abstract base class for callback recipients
       class Notifier {
       public:
-        virtual void notifyClipboardChanged(const char* text, int len) = 0;
+        virtual void notifyClipboardChanged(const char* text) = 0;
         virtual ~Notifier() {};
       };
 
diff --git a/win/rfb_win32/SDisplay.cxx b/win/rfb_win32/SDisplay.cxx
index 2cedc4a..2c91e3f 100644
--- a/win/rfb_win32/SDisplay.cxx
+++ b/win/rfb_win32/SDisplay.cxx
@@ -1,4 +1,5 @@
 /* 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
@@ -328,19 +329,16 @@
   return false;
 }
 
-void SDisplay::clientCutText(const char* text, int len) {
-  CharArray clip_sz(len+1);
-  memcpy(clip_sz.buf, text, len);
-  clip_sz.buf[len] = 0;
-  clipboard->setClipText(clip_sz.buf);
+void SDisplay::clientCutText(const char* text) {
+  clipboard->setClipText(text);
 }
 
 
 void
-SDisplay::notifyClipboardChanged(const char* text, int len) {
+SDisplay::notifyClipboardChanged(const char* text) {
   vlog.debug("clipboard text changed");
   if (server)
-    server->serverCutText(text, len);
+    server->serverCutText(text);
 }
 
 
diff --git a/win/rfb_win32/SDisplay.h b/win/rfb_win32/SDisplay.h
index 6dbfabb..1773b78 100644
--- a/win/rfb_win32/SDisplay.h
+++ b/win/rfb_win32/SDisplay.h
@@ -1,4 +1,5 @@
 /* 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
@@ -77,11 +78,11 @@
                                    const char* userName);
       virtual void pointerEvent(const Point& pos, int buttonmask);
       virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
-      virtual void clientCutText(const char* str, int len);
+      virtual void clientCutText(const char* str);
 
       // -=- Clipboard
       
-      virtual void notifyClipboardChanged(const char* text, int len);
+      virtual void notifyClipboardChanged(const char* text);
 
       // -=- Display events