boundery check, https://github.com/rustdesk/rustdesk/issues/107
This commit is contained in:
parent
bebe136834
commit
879c300563
@ -139,12 +139,13 @@ pub fn get_cursor_data(hcursor: u64) -> ResultType<CursorData> {
|
|||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
bm_mask.bmWidthBytes,
|
bm_mask.bmWidthBytes,
|
||||||
|
bm_mask.bmHeight,
|
||||||
) > 0;
|
) > 0;
|
||||||
}
|
}
|
||||||
if do_outline {
|
if do_outline {
|
||||||
let mut outline = Vec::new();
|
let mut outline = Vec::new();
|
||||||
outline.resize(((width + 2) * (height + 2) * 4) as _, 0);
|
outline.resize(((width + 2) * (height + 2) * 4) as _, 0);
|
||||||
drawOutline(outline.as_mut_ptr(), cbits.as_ptr(), width, height);
|
drawOutline(outline.as_mut_ptr(), cbits.as_ptr(), width, height, outline.len() as _);
|
||||||
cbits = outline;
|
cbits = outline;
|
||||||
width += 2;
|
width += 2;
|
||||||
height += 2;
|
height += 2;
|
||||||
@ -285,7 +286,7 @@ fn fix_cursor_mask(
|
|||||||
cbits: &mut Vec<u8>,
|
cbits: &mut Vec<u8>,
|
||||||
width: usize,
|
width: usize,
|
||||||
height: usize,
|
height: usize,
|
||||||
width_bytes: usize,
|
bm_width_bytes: usize,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut pix_idx = 0;
|
let mut pix_idx = 0;
|
||||||
for _ in 0..height {
|
for _ in 0..height {
|
||||||
@ -298,12 +299,18 @@ fn fix_cursor_mask(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let packed_width_bytes = (width + 7) >> 3;
|
let packed_width_bytes = (width + 7) >> 3;
|
||||||
|
let bm_size = mbits.len();
|
||||||
|
let c_size = cbits.len();
|
||||||
|
|
||||||
// Pack and invert bitmap data (mbits)
|
// Pack and invert bitmap data (mbits)
|
||||||
// borrow from tigervnc
|
// borrow from tigervnc
|
||||||
for y in 0..height {
|
for y in 0..height {
|
||||||
for x in 0..packed_width_bytes {
|
for x in 0..packed_width_bytes {
|
||||||
mbits[y * packed_width_bytes + x] = !mbits[y * width_bytes + x];
|
let a = y * packed_width_bytes + x;
|
||||||
|
let b = y * bm_width_bytes + x;
|
||||||
|
if a < bm_size && b < bm_size {
|
||||||
|
mbits[a] = !mbits[b];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,15 +322,23 @@ fn fix_cursor_mask(
|
|||||||
let mut bitmask: u8 = 0x80;
|
let mut bitmask: u8 = 0x80;
|
||||||
for x in 0..width {
|
for x in 0..width {
|
||||||
let mask_idx = y * packed_width_bytes + (x >> 3);
|
let mask_idx = y * packed_width_bytes + (x >> 3);
|
||||||
let pix_idx = y * bytes_row + (x << 2);
|
if mask_idx < bm_size {
|
||||||
if (mbits[mask_idx] & bitmask) == 0 {
|
let pix_idx = y * bytes_row + (x << 2);
|
||||||
for b1 in 0..4 {
|
if (mbits[mask_idx] & bitmask) == 0 {
|
||||||
if cbits[pix_idx + b1] != 0 {
|
for b1 in 0..4 {
|
||||||
mbits[mask_idx] ^= bitmask;
|
let a = pix_idx + b1;
|
||||||
for b2 in b1..4 {
|
if a < c_size {
|
||||||
cbits[pix_idx + b2] = 0x00;
|
if cbits[a] != 0 {
|
||||||
|
mbits[mask_idx] ^= bitmask;
|
||||||
|
for b2 in b1..4 {
|
||||||
|
let b = pix_idx + b2;
|
||||||
|
if b < c_size {
|
||||||
|
cbits[b] = 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,11 +354,12 @@ fn fix_cursor_mask(
|
|||||||
for y in 0..height {
|
for y in 0..height {
|
||||||
for x in 0..width {
|
for x in 0..width {
|
||||||
let mask_idx = y * packed_width_bytes + (x >> 3);
|
let mask_idx = y * packed_width_bytes + (x >> 3);
|
||||||
let alpha = if (mbits[mask_idx] << (x & 0x7)) & 0x80 == 0 {
|
let mut alpha = 255;
|
||||||
0
|
if mask_idx < bm_size {
|
||||||
} else {
|
if (mbits[mask_idx] << (x & 0x7)) & 0x80 == 0 {
|
||||||
255
|
alpha = 0;
|
||||||
};
|
}
|
||||||
|
}
|
||||||
let a = cbits[pix_idx + 2];
|
let a = cbits[pix_idx + 2];
|
||||||
let b = cbits[pix_idx + 1];
|
let b = cbits[pix_idx + 1];
|
||||||
let c = cbits[pix_idx];
|
let c = cbits[pix_idx];
|
||||||
@ -377,9 +393,9 @@ extern "C" {
|
|||||||
fn LaunchProcessWin(cmd: *const u16, session_id: DWORD, as_user: BOOL) -> HANDLE;
|
fn LaunchProcessWin(cmd: *const u16, session_id: DWORD, as_user: BOOL) -> HANDLE;
|
||||||
fn selectInputDesktop() -> BOOL;
|
fn selectInputDesktop() -> BOOL;
|
||||||
fn inputDesktopSelected() -> BOOL;
|
fn inputDesktopSelected() -> BOOL;
|
||||||
fn handleMask(out: *mut u8, mask: *const u8, width: i32, height: i32, bmWidthBytes: i32)
|
fn handleMask(out: *mut u8, mask: *const u8, width: i32, height: i32, bmWidthBytes: i32, bmHeight: i32)
|
||||||
-> i32;
|
-> i32;
|
||||||
fn drawOutline(out: *mut u8, in_: *const u8, width: i32, height: i32);
|
fn drawOutline(out: *mut u8, in_: *const u8, width: i32, height: i32, out_size: i32);
|
||||||
fn get_di_bits(out: *mut u8, dc: HDC, hbmColor: HBITMAP, width: i32, height: i32) -> i32;
|
fn get_di_bits(out: *mut u8, dc: HDC, hbmColor: HBITMAP, width: i32, height: i32) -> i32;
|
||||||
fn blank_screen(v: BOOL);
|
fn blank_screen(v: BOOL);
|
||||||
fn BlockInput(v: BOOL) -> BOOL;
|
fn BlockInput(v: BOOL) -> BOOL;
|
||||||
|
@ -192,10 +192,13 @@ extern "C"
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int handleMask(uint8_t *rwbuffer, const uint8_t *mask, int width, int height, int bmWidthBytes)
|
int handleMask(uint8_t *rwbuffer, const uint8_t *mask, int width, int height, int bmWidthBytes, int bmHeight)
|
||||||
{
|
{
|
||||||
auto andMask = mask;
|
auto andMask = mask;
|
||||||
auto xorMask = mask + height * bmWidthBytes;
|
auto andMaskSize = bmWidthBytes * bmHeight;
|
||||||
|
auto offset = height * bmWidthBytes;
|
||||||
|
auto xorMask = mask + offset;
|
||||||
|
auto xorMaskSize = andMaskSize - offset;
|
||||||
int doOutline = 0;
|
int doOutline = 0;
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
@ -204,7 +207,7 @@ extern "C"
|
|||||||
int byte = y * bmWidthBytes + x / 8;
|
int byte = y * bmWidthBytes + x / 8;
|
||||||
int bit = 7 - x % 8;
|
int bit = 7 - x % 8;
|
||||||
|
|
||||||
if (!(andMask[byte] & (1 << bit)))
|
if (byte < andMaskSize && !(andMask[byte] & (1 << bit)))
|
||||||
{
|
{
|
||||||
// Valid pixel, so make it opaque
|
// Valid pixel, so make it opaque
|
||||||
rwbuffer[3] = 0xff;
|
rwbuffer[3] = 0xff;
|
||||||
@ -215,7 +218,7 @@ extern "C"
|
|||||||
else
|
else
|
||||||
rwbuffer[0] = rwbuffer[1] = rwbuffer[2] = 0;
|
rwbuffer[0] = rwbuffer[1] = rwbuffer[2] = 0;
|
||||||
}
|
}
|
||||||
else if (xorMask[byte] & (1 << bit))
|
else if (byte < xorMaskSize && xorMask[byte] & (1 << bit))
|
||||||
{
|
{
|
||||||
// Replace any XORed pixels with black, because RFB doesn't support
|
// Replace any XORed pixels with black, because RFB doesn't support
|
||||||
// XORing of cursors. XORing is used for the I-beam cursor, which is most
|
// XORing of cursors. XORing is used for the I-beam cursor, which is most
|
||||||
@ -240,10 +243,12 @@ extern "C"
|
|||||||
return doOutline;
|
return doOutline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawOutline(uint8_t *out0, const uint8_t *in0, int width, int height)
|
void drawOutline(uint8_t *out0, const uint8_t *in0, int width, int height, int out0_size)
|
||||||
{
|
{
|
||||||
auto in = in0;
|
auto in = in0;
|
||||||
auto out = out0 + width * 4 + 4;
|
auto out0_end = out0 + out0_size;
|
||||||
|
auto offset = width * 4 + 4;
|
||||||
|
auto out = out0 + offset;
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < width; x++)
|
for (int x = 0; x < width; x++)
|
||||||
@ -251,12 +256,16 @@ extern "C"
|
|||||||
// Visible pixel?
|
// Visible pixel?
|
||||||
if (in[3] > 0)
|
if (in[3] > 0)
|
||||||
{
|
{
|
||||||
|
auto n = 4 * 3;
|
||||||
|
auto p = out - (width + 2) * 4 - 4;
|
||||||
// Outline above...
|
// Outline above...
|
||||||
memset(out - (width + 2) * 4 - 4, 0xff, 4 * 3);
|
if (p >= out0 && p + n <= out0_end) memset(p, 0xff, n);
|
||||||
// ...besides...
|
// ...besides...
|
||||||
memset(out - 4, 0xff, 4 * 3);
|
p = out - 4;
|
||||||
|
if (p + n <= out0_end) memset(p, 0xff, n);
|
||||||
// ...and above
|
// ...and above
|
||||||
memset(out + (width + 2) * 4 - 4, 0xff, 4 * 3);
|
p = out + (width + 2) * 4 - 4;
|
||||||
|
if (p + n <= out0_end) memset(p, 0xff, n);
|
||||||
}
|
}
|
||||||
in += 4;
|
in += 4;
|
||||||
out += 4;
|
out += 4;
|
||||||
@ -267,12 +276,12 @@ extern "C"
|
|||||||
|
|
||||||
// Pass 2, overwrite with actual cursor
|
// Pass 2, overwrite with actual cursor
|
||||||
in = in0;
|
in = in0;
|
||||||
out = out0 + width * 4 + 4;
|
out = out0 + offset;
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < width; x++)
|
for (int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
if (in[3] > 0)
|
if (in[3] > 0 && out + 4 <= out0_end)
|
||||||
memcpy(out, in, 4);
|
memcpy(out, in, 4);
|
||||||
in += 4;
|
in += 4;
|
||||||
out += 4;
|
out += 4;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user