From 5e8227d30aa5b1af30b28da34521aa6166f1ec9e Mon Sep 17 00:00:00 2001 From: "Brian P. Hinz" Date: Thu, 3 Aug 2017 21:14:54 -0400 Subject: [PATCH] Fix for NPE when zero width or height alpha cursor is sent --- java/com/tigervnc/rfb/CMsgReader.java | 31 +++++++++---------- java/com/tigervnc/rfb/ManagedPixelBuffer.java | 14 +++++++-- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/java/com/tigervnc/rfb/CMsgReader.java b/java/com/tigervnc/rfb/CMsgReader.java index a5cc267f..a79cf842 100644 --- a/java/com/tigervnc/rfb/CMsgReader.java +++ b/java/com/tigervnc/rfb/CMsgReader.java @@ -314,7 +314,8 @@ public class CMsgReader { new ManagedPixelBuffer(rgbaPF, width, height); PixelFormat origPF; - DataBufferInt buf; + ByteBuffer buf = + ByteBuffer.allocate(pb.area()*4).order(rgbaPF.getByteOrder());; encoding = is.readS32(); @@ -323,28 +324,26 @@ public class CMsgReader { handler.readAndDecodeRect(pb.getRect(), encoding, pb); handler.cp.setPF(origPF); - if (pb.getRect().area() == 0) - return; - // ARGB with pre-multiplied alpha works best for BufferedImage - buf = (DataBufferInt)pb.getBufferRW(pb.getRect()).getDataBuffer(); - ByteBuffer bbuf = - ByteBuffer.allocate(pb.area()*4).order(rgbaPF.getByteOrder()); - bbuf.asIntBuffer().put(buf.getData()).flip().mark(); + if (pb.area() > 0) { + // Sometimes a zero width or height cursor is sent. + DataBuffer db = pb.getBuffer(pb.getRect()).getDataBuffer(); + for (int i = 0;i < pb.area();i++) + buf.asIntBuffer().put(i, db.getElem(i)); + } for (int i = 0;i < pb.area();i++) { - byte alpha = bbuf.get(bbuf.position()+3); + byte alpha = buf.get(buf.position()+3); - bbuf.put(i*4+3, (byte)(bbuf.get(i*4+2))); - bbuf.put(i*4+2, (byte)(bbuf.get(i*4+1))); - bbuf.put(i*4+1, (byte)(bbuf.get(i*4+0))); - bbuf.put(i*4+0, (byte)alpha); + buf.put(i*4+3, buf.get(i*4+2)); + buf.put(i*4+2, buf.get(i*4+1)); + buf.put(i*4+1, buf.get(i*4+0)); + buf.put(i*4+0, alpha); - bbuf.position(bbuf.position() + 4); + buf.position(buf.position() + 4); } - handler.setCursor(width, height, hotspot, - bbuf.array()); + handler.setCursor(width, height, hotspot, buf.array()); } protected void readSetDesktopName(int x, int y, int w, int h) diff --git a/java/com/tigervnc/rfb/ManagedPixelBuffer.java b/java/com/tigervnc/rfb/ManagedPixelBuffer.java index 6e14b92e..028eadc6 100644 --- a/java/com/tigervnc/rfb/ManagedPixelBuffer.java +++ b/java/com/tigervnc/rfb/ManagedPixelBuffer.java @@ -18,6 +18,8 @@ package com.tigervnc.rfb; +import java.awt.image.*; + public class ManagedPixelBuffer extends FullFramePixelBuffer { public ManagedPixelBuffer() { @@ -43,9 +45,15 @@ public class ManagedPixelBuffer extends FullFramePixelBuffer { final void checkDataSize() { int new_datasize = width_ * height_; if (datasize < new_datasize) { - vlog.debug("reallocating managed buffer ("+width_+"x"+height_+")"); - if (format != null) - data = PixelFormat.getColorModel(format).createCompatibleWritableRaster(width_, height_); + if (data != null) { + datasize = 0; data = null; + } + if (new_datasize > 0) { + ColorModel cm = format.getColorModel(); + data = cm.createCompatibleWritableRaster(width_, height_); + image = new BufferedImage(cm, data, cm.isAlphaPremultiplied(), null); + datasize = new_datasize; + } } } -- 2.39.5