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,