From d121c1430dd55da0a1ca6160606cc180946f2401 Mon Sep 17 00:00:00 2001 From: Brian Hinz Date: Sat, 11 Jan 2014 23:07:42 +0000 Subject: [PATCH] r5138 did not completely resolve the problem with clipboard data consuming too much heap space. Large amounts of clipboard data could still cause the heap size to grow to huge sizes. This patch tries to address the problem by opening a Reader to the underlying IO stream and then reading only up to MaxCutText characters. The garbage collector is invoked manually rather than waiting for the JVM to do it in order to prevent the heap size from growing in between JVM invoked garbage collections. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@5155 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- .../tigervnc/vncviewer/ClipboardDialog.java | 5 +++ .../com/tigervnc/vncviewer/DesktopWindow.java | 42 ++++++++++--------- java/com/tigervnc/vncviewer/VncViewer.java | 2 +- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/java/com/tigervnc/vncviewer/ClipboardDialog.java b/java/com/tigervnc/vncviewer/ClipboardDialog.java index 2c9b7d0f..d4cde6e1 100644 --- a/java/com/tigervnc/vncviewer/ClipboardDialog.java +++ b/java/com/tigervnc/vncviewer/ClipboardDialog.java @@ -57,6 +57,11 @@ class ClipboardDialog extends Dialog implements ActionListener { pack(); } + public boolean compareContentsTo(String str) { + return str.equals(textArea.getText()); + + } + public void setContents(String str) { textArea.setText(str); } diff --git a/java/com/tigervnc/vncviewer/DesktopWindow.java b/java/com/tigervnc/vncviewer/DesktopWindow.java index 4175746f..e78ee277 100644 --- a/java/com/tigervnc/vncviewer/DesktopWindow.java +++ b/java/com/tigervnc/vncviewer/DesktopWindow.java @@ -35,6 +35,8 @@ import java.awt.image.*; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.Clipboard; +import java.io.BufferedReader; +import java.nio.CharBuffer; import javax.swing.*; import com.tigervnc.rfb.*; @@ -362,28 +364,28 @@ class DesktopWindow extends JPanel implements Runnable, MouseListener, try { if (sm != null) sm.checkSystemClipboardAccess(); Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); - if (cb == null) return; - Transferable t = cb.getContents(null); - if ((t != null) && t.isDataFlavorSupported(DataFlavor.stringFlavor)) { - try { - String newContents = new String(""); - if (t.getTransferData(DataFlavor.stringFlavor) != null) { - int len = Math.min(cc.viewer.maxCutText.getValue(), - ((String)t.getTransferData(DataFlavor.stringFlavor)).length()); - newContents = - ((String)t.getTransferData(DataFlavor.stringFlavor)).substring(0, len); - } - if (!newContents.equals(cc.clipboardDialog.getContents())) { - if (cc.viewer.sendClipboard.getValue()) - cc.writeClientCutText(newContents, newContents.length()); - cc.clipboardDialog.setContents(newContents); - } - } catch(java.lang.Exception e) { - vlog.debug("Exception getting clipboard data: " + e.getMessage()); + if (cb != null) { + Transferable t = cb.getContents(null); + if (t == null) return; + DataFlavor flavor = + DataFlavor.selectBestTextFlavor(t.getTransferDataFlavors()); + if (flavor == null) return; + BufferedReader br = new BufferedReader(flavor.getReaderForText(t)); + CharBuffer cbuf = + CharBuffer.allocate(VncViewer.maxCutText.getValue()); + br.read(cbuf); + cbuf.flip(); + String newContents = cbuf.toString(); + if (!cc.clipboardDialog.compareContentsTo(newContents)) { + cc.clipboardDialog.setContents(newContents); + if (cc.viewer.sendClipboard.getValue()) + cc.writeClientCutText(newContents, newContents.length()); } + br.close(); + System.gc(); } - } catch(SecurityException e) { - vlog.debug("Cannot access the system clipboard"); + } catch(java.lang.Exception e) { + vlog.debug("Exception getting clipboard data: " + e.getMessage()); } } diff --git a/java/com/tigervnc/vncviewer/VncViewer.java b/java/com/tigervnc/vncviewer/VncViewer.java index 8d9b23a6..87820e3c 100644 --- a/java/com/tigervnc/vncviewer/VncViewer.java +++ b/java/com/tigervnc/vncviewer/VncViewer.java @@ -561,7 +561,7 @@ public class VncViewer extends javax.swing.JApplet = new BoolParameter("SendClipboard", "Send clipboard changes to the server", true); - IntParameter maxCutText + static IntParameter maxCutText = new IntParameter("MaxCutText", "Maximum permitted length of an outgoing clipboard update", 262144); -- 2.39.5