From a356a706526ac4182b3ae144166ae04271b85258 Mon Sep 17 00:00:00 2001 From: "Brian P. Hinz" Date: Sat, 21 Dec 2019 16:51:33 -0500 Subject: [PATCH] Mostly stylistic changes to java viewer to match recent changes to native viewer --- java/com/tigervnc/rdr/FdInStream.java | 8 ++-- java/com/tigervnc/rdr/FdOutStream.java | 9 ++-- java/com/tigervnc/rdr/InStream.java | 21 ++++++---- java/com/tigervnc/rdr/MemOutStream.java | 4 ++ java/com/tigervnc/rdr/OutStream.java | 23 +++++----- java/com/tigervnc/rdr/TLSInStream.java | 10 +++-- java/com/tigervnc/rdr/TLSOutStream.java | 14 +++---- java/com/tigervnc/rdr/ZlibInStream.java | 21 ++++++---- java/com/tigervnc/rfb/ManagedPixelBuffer.java | 1 + .../tigervnc/rfb/ModifiablePixelBuffer.java | 6 +-- java/com/tigervnc/rfb/PixelBuffer.java | 21 +++++++++- java/com/tigervnc/rfb/PixelFormat.java | 18 +++++++- java/com/tigervnc/rfb/TightDecoder.java | 42 ++++++++++--------- java/com/tigervnc/rfb/ZRLEDecoder.java | 3 +- java/com/tigervnc/vncviewer/Parameters.java | 4 +- 15 files changed, 129 insertions(+), 76 deletions(-) diff --git a/java/com/tigervnc/rdr/FdInStream.java b/java/com/tigervnc/rdr/FdInStream.java index 8b3c7e2c..0178f451 100644 --- a/java/com/tigervnc/rdr/FdInStream.java +++ b/java/com/tigervnc/rdr/FdInStream.java @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright (C) 2012,2014 Brian P. Hinz + * Copyright (C) 2012-2019 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -149,8 +149,10 @@ public class FdInStream extends InStream { end += n; } - if (itemSize * nItems > end - ptr) - nItems = (end - ptr) / itemSize; + int nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } diff --git a/java/com/tigervnc/rdr/FdOutStream.java b/java/com/tigervnc/rdr/FdOutStream.java index acb03a29..e04b8287 100644 --- a/java/com/tigervnc/rdr/FdOutStream.java +++ b/java/com/tigervnc/rdr/FdOutStream.java @@ -1,6 +1,6 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. * Copyright 2011 Pierre Ossman for Cendio AB - * Copyright (C) 2012,2014 Brian P. Hinz + * Copyright (C) 2012-2019 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -121,9 +121,10 @@ public class FdOutStream extends OutStream { } } - // Can we fit all the items asked for? - if (itemSize * nItems > end - ptr) - nItems = (end - ptr) / itemSize; + int nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } diff --git a/java/com/tigervnc/rdr/InStream.java b/java/com/tigervnc/rdr/InStream.java index 58afcfb6..f3770a09 100644 --- a/java/com/tigervnc/rdr/InStream.java +++ b/java/com/tigervnc/rdr/InStream.java @@ -1,4 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright (C) 2011-2019 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,12 +35,15 @@ abstract public class InStream { // maximum of nItems). public int check(int itemSize, int nItems, boolean wait) { - if (ptr + itemSize * nItems > end) { - if (ptr + itemSize > end) + int nAvail; + + if (itemSize > (end - ptr)) return overrun(itemSize, nItems, wait); - nItems = (end - ptr) / itemSize; - } + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; + return nItems; } @@ -101,12 +105,11 @@ abstract public class InStream { // readBytes() reads an exact number of bytes public void readBytes(ByteBuffer data, int length) { - ByteBuffer dataPtr = data; - int dataEnd = dataPtr.position() + length; - while (dataPtr.position() < dataEnd) { - int n = check(1, dataEnd - dataPtr.position()); - dataPtr.put(b, ptr, n); + while (length > 0) { + int n = check(1, length); + data.put(b, ptr, n); ptr += n; + length -= n; } } diff --git a/java/com/tigervnc/rdr/MemOutStream.java b/java/com/tigervnc/rdr/MemOutStream.java index 6e53ccfa..3df4635b 100644 --- a/java/com/tigervnc/rdr/MemOutStream.java +++ b/java/com/tigervnc/rdr/MemOutStream.java @@ -1,4 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright (C) 2011-2019 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,6 +48,9 @@ public class MemOutStream extends OutStream { if (len < end * 2) len = end * 2; + if (len < end) + throw new Exception("Overflow in MemOutStream::overrun()"); + byte[] newBuf = new byte[len]; System.arraycopy(b, 0, newBuf, 0, ptr); b = newBuf; diff --git a/java/com/tigervnc/rdr/OutStream.java b/java/com/tigervnc/rdr/OutStream.java index 0e201339..be36819f 100644 --- a/java/com/tigervnc/rdr/OutStream.java +++ b/java/com/tigervnc/rdr/OutStream.java @@ -1,4 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright (C) 2011-2019 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,12 +35,15 @@ abstract public class OutStream { // of nItems). public final int check(int itemSize, int nItems) { - if (ptr + itemSize * nItems > end) { - if (ptr + itemSize > end) - return overrun(itemSize, nItems); + int nAvail; + + if (itemSize > (end - ptr)) + return overrun(itemSize, nItems); + + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; - nItems = (end - ptr) / itemSize; - } return nItems; } @@ -119,12 +123,11 @@ abstract public class OutStream { } public void writeBytes(ByteBuffer data, int length) { - ByteBuffer dataPtr = data; - int dataEnd = dataPtr.position() + length; - while (dataPtr.position() < dataEnd) { - int n = check(1, dataEnd - dataPtr.position()); - dataPtr.get(b, ptr, n); + while (length > 0) { + int n = check(1, length); + data.get(b, ptr, n); ptr += n; + length -= n; } } diff --git a/java/com/tigervnc/rdr/TLSInStream.java b/java/com/tigervnc/rdr/TLSInStream.java index c0e57a61..b19731aa 100644 --- a/java/com/tigervnc/rdr/TLSInStream.java +++ b/java/com/tigervnc/rdr/TLSInStream.java @@ -1,7 +1,7 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. * Copyright (C) 2005 Martin Koegler * Copyright (C) 2010 TigerVNC Team - * Copyright (C) 2011 Brian P. Hinz + * Copyright (C) 2011-2019 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,15 +72,17 @@ public class TLSInStream extends InStream { end -= ptr - start; ptr = start; - while (end < start + itemSize) { + while ((end - start) < itemSize) { int n = readTLS(b, end, start + bufSize - end, wait); if (!wait && n == 0) return 0; end += n; } - if (itemSize * nItems > end - ptr) - nItems = (end - ptr) / itemSize; + int nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } diff --git a/java/com/tigervnc/rdr/TLSOutStream.java b/java/com/tigervnc/rdr/TLSOutStream.java index f5685d5b..30977af8 100644 --- a/java/com/tigervnc/rdr/TLSOutStream.java +++ b/java/com/tigervnc/rdr/TLSOutStream.java @@ -1,7 +1,7 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. * Copyright (C) 2005 Martin Koegler * Copyright (C) 2010 TigerVNC Team - * Copyright (C) 2011 Brian P. Hinz + * Copyright (C) 2011-2019 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -56,7 +56,6 @@ public class TLSOutStream extends OutStream { } ptr = start; - //out.flush(); } protected int overrun(int itemSize, int nItems) @@ -66,8 +65,10 @@ public class TLSOutStream extends OutStream { flush(); - if (itemSize * nItems > end - ptr) - nItems = (end - ptr) / itemSize; + int nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } @@ -81,11 +82,6 @@ public class TLSOutStream extends OutStream { } catch (java.io.IOException e) { throw new Exception(e.getMessage()); } - //if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN) - // return 0; - - //if (n < 0) - // throw new TLSException("writeTLS", n); return n; } diff --git a/java/com/tigervnc/rdr/ZlibInStream.java b/java/com/tigervnc/rdr/ZlibInStream.java index 12de0e8b..51752e3d 100644 --- a/java/com/tigervnc/rdr/ZlibInStream.java +++ b/java/com/tigervnc/rdr/ZlibInStream.java @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright (C) 2011 Brian P. Hinz + * Copyright (C) 2011-2019 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -51,16 +51,16 @@ public class ZlibInStream extends InStream { return offset + ptr - start; } - public void removeUnderlying() + public void flushUnderlying() { ptr = end = start; - if (underlying == null) return; while (bytesIn > 0) { decompress(true); end = start; // throw away any data } - underlying = null; + + setUnderlying(null, 0); } public void reset() @@ -86,7 +86,7 @@ public class ZlibInStream extends InStream { public void deinit() { assert(zs != null); - removeUnderlying(); + setUnderlying(null, 0); zs.inflateEnd(); zs = null; } @@ -95,8 +95,6 @@ public class ZlibInStream extends InStream { { if (itemSize > bufSize) throw new Exception("ZlibInStream overrun: max itemSize exceeded"); - if (underlying == null) - throw new Exception("ZlibInStream overrun: no underlying stream"); if (end - ptr != 0) System.arraycopy(b, ptr, b, start, end - ptr); @@ -110,8 +108,10 @@ public class ZlibInStream extends InStream { return 0; } - if (itemSize * nItems > end - ptr) - nItems = (end - ptr) / itemSize; + int nAvail; + nAvail = (end - ptr) / itemSize; + if (nAvail < nItems) + return nAvail; return nItems; } @@ -123,6 +123,9 @@ public class ZlibInStream extends InStream { private boolean decompress(boolean wait) { + if (underlying == null) + throw new Exception("ZlibInStream overrun: no underlying stream"); + zs.next_out = b; zs.next_out_index = end; zs.avail_out = start + bufSize - end; diff --git a/java/com/tigervnc/rfb/ManagedPixelBuffer.java b/java/com/tigervnc/rfb/ManagedPixelBuffer.java index 028eadc6..4452feec 100644 --- a/java/com/tigervnc/rfb/ManagedPixelBuffer.java +++ b/java/com/tigervnc/rfb/ManagedPixelBuffer.java @@ -1,4 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright 2016-2019 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/java/com/tigervnc/rfb/ModifiablePixelBuffer.java b/java/com/tigervnc/rfb/ModifiablePixelBuffer.java index 49252771..1884010c 100644 --- a/java/com/tigervnc/rfb/ModifiablePixelBuffer.java +++ b/java/com/tigervnc/rfb/ModifiablePixelBuffer.java @@ -1,4 +1,4 @@ -/* Copyright 2016 Brian P. Hinz +/* Copyright 2016-2019 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -115,7 +115,7 @@ public abstract class ModifiablePixelBuffer extends PixelBuffer if (!drect.enclosed_by(getRect())) { String msg = "Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d"; vlog.error(String.format(msg, drect.width(), drect.height(), - drect.tl.x, drect.tl.y, width_, height_)); + drect.tl.x, drect.tl.y, width(), height())); drect = drect.intersect(getRect()); } @@ -126,7 +126,7 @@ public abstract class ModifiablePixelBuffer extends PixelBuffer if (!srect.enclosed_by(getRect())) { String msg = "Source rect %dx%d at %d,%d exceeds framebuffer %dx%d"; vlog.error(String.format(msg, srect.width(), srect.height(), - srect.tl.x, srect.tl.y, width_, height_)); + srect.tl.x, srect.tl.y, width(), height())); srect = srect.intersect(getRect()); // Need to readjust the destination now that the area has changed drect = srect.translate(move_by_delta); diff --git a/java/com/tigervnc/rfb/PixelBuffer.java b/java/com/tigervnc/rfb/PixelBuffer.java index 18d84d5d..32a40ebc 100644 --- a/java/com/tigervnc/rfb/PixelBuffer.java +++ b/java/com/tigervnc/rfb/PixelBuffer.java @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2016 Brian P. Hinz + * Copyright 2016-2019 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,10 +29,18 @@ import java.util.concurrent.atomic.*; public abstract class PixelBuffer { + // We do a lot of byte offset calculations that assume the result fits + // inside a signed 32 bit integer. Limit the maximum size of pixel + // buffers so that these calculations never overflow. + + static final int maxPixelBufferWidth = 16384; + static final int maxPixelBufferHeight = 16384; + public PixelBuffer(PixelFormat pf, int w, int h) { format = pf; width_ = w; height_= h; + setSize(w, h); } protected PixelBuffer() { width_ = 0; height_ = 0; } @@ -72,6 +80,17 @@ public abstract class PixelBuffer { // const Rect& r, int stride=0) const; public Image getImage() { return image; } + public void setSize(int width, int height) + { + if ((width < 0) || (width > maxPixelBufferWidth)) + throw new Exception("Invalid PixelBuffer width of "+width+" pixels requested"); + if ((height < 0) || (height > maxPixelBufferHeight)) + throw new Exception("Invalid PixelBuffer height of "+height+" pixels requested"); + + width_ = width; + height_ = height; + } + /////////////////////////////////////////////// // Framebuffer update methods // diff --git a/java/com/tigervnc/rfb/PixelFormat.java b/java/com/tigervnc/rfb/PixelFormat.java index 593b7804..428f501f 100644 --- a/java/com/tigervnc/rfb/PixelFormat.java +++ b/java/com/tigervnc/rfb/PixelFormat.java @@ -41,7 +41,8 @@ public class PixelFormat { redMax = rm; greenMax = gm; blueMax = bm; redShift = rs; greenShift = gs; blueShift = bs; converters = new HashMap(); - assert(isSane()); + if (!isSane()) + throw new Exception("invalid pixel format"); updateState(); } @@ -167,6 +168,12 @@ public class PixelFormat { return false; if(blueMax != 255) return false; + if ((redShift & 0x7) != 0) + return false; + if ((greenShift & 0x7) != 0) + return false; + if ((blueShift & 0x7) != 0) + return false; return true; } @@ -503,7 +510,14 @@ public class PixelFormat { return false; totalBits = bits(redMax) + bits(greenMax) + bits(blueMax); - if (totalBits > bpp) + if (totalBits > depth) + return false; + + if ((bits(redMax) + redShift) > bpp) + return false; + if ((bits(greenMax) + greenShift) > bpp) + return false; + if ((bits(blueMax) + blueShift) > bpp) return false; if (((redMax << redShift) & (greenMax << greenShift)) != 0) diff --git a/java/com/tigervnc/rfb/TightDecoder.java b/java/com/tigervnc/rfb/TightDecoder.java index f8cd23c3..2f7621d6 100644 --- a/java/com/tigervnc/rfb/TightDecoder.java +++ b/java/com/tigervnc/rfb/TightDecoder.java @@ -334,7 +334,8 @@ public class TightDecoder extends Decoder { zis[streamId].readBytes(netbuf, dataSize); - zis[streamId].removeUnderlying(); + zis[streamId].flushUnderlying(); + zis[streamId].setUnderlying(null, 0); ms = null; bufptr = (ByteBuffer)netbuf.flip(); @@ -421,15 +422,17 @@ public class TightDecoder extends Decoder { int rectWidth = r.width(); for (y = 0; y < rectHeight; y++) { - /* First pixel in a row */ - for (c = 0; c < 3; c++) { - pix.put(c, (byte)(inbuf.get(y*rectWidth*3+c) + prevRow[c])); - thisRow[c] = pix.get(c); - } - pf.bufferFromRGB((ByteBuffer)outbuf.duplicate().position(y*stride), pix, 1); + for (x = 0; x < rectWidth; x++) { + /* First pixel in a row */ + if (x == 0) { + for (c = 0; c < 3; c++) { + pix.put(c, (byte)(inbuf.get(y*rectWidth*3+c) + prevRow[c])); + thisRow[c] = pix.get(c); + } + pf.bufferFromRGB((ByteBuffer)outbuf.duplicate().position(y*stride), pix, 1); + continue; + } - /* Remaining pixels of a row */ - for (x = 1; x < rectWidth; x++) { for (c = 0; c < 3; c++) { est[c] = prevRow[x*3+c] + pix.get(c) - prevRow[(x-1)*3+c]; if (est[c] > 0xff) { @@ -462,17 +465,18 @@ public class TightDecoder extends Decoder { int rectWidth = r.width(); for (y = 0; y < rectHeight; y++) { - /* First pixel in a row */ - pf.rgbFromBuffer(pix.duplicate(), (ByteBuffer)inbuf.position(y*rectWidth), 1); - for (c = 0; c < 3; c++) - pix.put(c, (byte)(pix.get(c) + prevRow[c])); - - System.arraycopy(pix.array(), 0, thisRow, 0, pix.capacity()); - - pf.bufferFromRGB((ByteBuffer)outbuf.duplicate().position(y*stride), pix, 1); + for (x = 0; x < rectWidth; x++) { + /* First pixel in a row */ + if (x == 0) { + pf.rgbFromBuffer(pix.duplicate(), (ByteBuffer)inbuf.position(y*rectWidth), 1); + for (c = 0; c < 3; c++) + pix.put(c, (byte)(pix.get(c) + prevRow[c])); + + System.arraycopy(pix.array(), 0, thisRow, 0, pix.capacity()); + pf.bufferFromRGB((ByteBuffer)outbuf.duplicate().position(y*stride), pix, 1); + continue; + } - /* Remaining pixels of a row */ - for (x = 1; x < rectWidth; x++) { for (c = 0; c < 3; c++) { est[c] = prevRow[x*3+c] + pix.get(c) - prevRow[(x-1)*3+c]; if (est[c] > 0xff) { diff --git a/java/com/tigervnc/rfb/ZRLEDecoder.java b/java/com/tigervnc/rfb/ZRLEDecoder.java index bd49ab43..e9add505 100644 --- a/java/com/tigervnc/rfb/ZRLEDecoder.java +++ b/java/com/tigervnc/rfb/ZRLEDecoder.java @@ -288,7 +288,8 @@ public class ZRLEDecoder extends Decoder { } } - zis.removeUnderlying(); + zis.flushUnderlying(); + zis.setUnderlying(null, 0); } private ZlibInStream zis; diff --git a/java/com/tigervnc/vncviewer/Parameters.java b/java/com/tigervnc/vncviewer/Parameters.java index 7be37789..b5144156 100644 --- a/java/com/tigervnc/vncviewer/Parameters.java +++ b/java/com/tigervnc/vncviewer/Parameters.java @@ -262,8 +262,8 @@ public class Parameters { public static IntParameter compressLevel = new IntParameter("CompressLevel", - "Use specified compression level. 0 = Low, 9 = High", - 1); + "Use specified lossless compression level. 0 = Low, 9 = High. Default is 2.", + 2); public static BoolParameter noJpeg = new BoolParameter("NoJPEG", -- 2.39.5