From 4c7f5dd24a246ebb3f41d7f2f552a1a995a47efb Mon Sep 17 00:00:00 2001 From: aniket866 Date: Sun, 15 Feb 2026 01:30:29 +0530 Subject: [PATCH 1/4] fixing-input-validation --- src/server/InputHandler.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/server/InputHandler.ts b/src/server/InputHandler.ts index 77ffe46..1c17ccd 100644 --- a/src/server/InputHandler.ts +++ b/src/server/InputHandler.ts @@ -14,11 +14,32 @@ export interface InputMessage { } export class InputHandler { + private lastEventTime = 0; + constructor() { mouse.config.mouseSpeed = 1000; } async handleMessage(msg: InputMessage) { + // Validation: Text length sanitation + if (msg.text && msg.text.length > 500) { + msg.text = msg.text.substring(0, 500); + } + + // Validation: Sane bounds for coordinates + const MAX_COORD = 2000; + if (msg.dx !== undefined) msg.dx = Math.max(-MAX_COORD, Math.min(MAX_COORD, msg.dx)); + if (msg.dy !== undefined) msg.dy = Math.max(-MAX_COORD, Math.min(MAX_COORD, msg.dy)); + + // Throttling: Limit high-frequency events to ~60fps (16ms) + if (msg.type === 'move' || msg.type === 'scroll') { + const now = Date.now(); + if (now - this.lastEventTime < 16) { + return; + } + this.lastEventTime = now; + } + switch (msg.type) { case 'move': if (msg.dx !== undefined && msg.dy !== undefined) { From 47c06d49d7b0e9fd3102d24d2932177405265779 Mon Sep 17 00:00:00 2001 From: Aniket Date: Sun, 15 Feb 2026 01:45:02 +0530 Subject: [PATCH 2/4] Code rabbit follow up Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- src/server/InputHandler.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/server/InputHandler.ts b/src/server/InputHandler.ts index 1c17ccd..f32b7c4 100644 --- a/src/server/InputHandler.ts +++ b/src/server/InputHandler.ts @@ -28,8 +28,12 @@ export class InputHandler { // Validation: Sane bounds for coordinates const MAX_COORD = 2000; - if (msg.dx !== undefined) msg.dx = Math.max(-MAX_COORD, Math.min(MAX_COORD, msg.dx)); - if (msg.dy !== undefined) msg.dy = Math.max(-MAX_COORD, Math.min(MAX_COORD, msg.dy)); + if (typeof msg.dx === 'number' && Number.isFinite(msg.dx)) { + msg.dx = Math.max(-MAX_COORD, Math.min(MAX_COORD, msg.dx)); + } + if (typeof msg.dy === 'number' && Number.isFinite(msg.dy)) { + msg.dy = Math.max(-MAX_COORD, Math.min(MAX_COORD, msg.dy)); + } // Throttling: Limit high-frequency events to ~60fps (16ms) if (msg.type === 'move' || msg.type === 'scroll') { From 26dc7fffc05ff7ec8c401d7dcf20d15127df35bf Mon Sep 17 00:00:00 2001 From: Aniket Date: Sun, 15 Feb 2026 01:46:28 +0530 Subject: [PATCH 3/4] Code rabbit follow-up --- src/server/InputHandler.ts | 43 +++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/src/server/InputHandler.ts b/src/server/InputHandler.ts index f32b7c4..ba78bf5 100644 --- a/src/server/InputHandler.ts +++ b/src/server/InputHandler.ts @@ -5,7 +5,7 @@ export interface InputMessage { type: 'move' | 'click' | 'scroll' | 'key' | 'text' | 'zoom' | 'combo'; dx?: number; dy?: number; - button?: 'left' | 'right' | 'middle'; + button?: 'left' | 'right'' | 'middle'; press?: boolean; key?: string; keys?: string[]; @@ -14,7 +14,12 @@ export interface InputMessage { } export class InputHandler { - private lastEventTime = 0; + private lastMoveTime = 0; + private lastScrollTime = 0; + private pendingMove: InputMessage | null = null; + private pendingScroll: InputMessage | null = null; + private moveTimer: ReturnType | null = null; + private scrollTimer: ReturnType | null = null; constructor() { mouse.config.mouseSpeed = 1000; @@ -36,12 +41,40 @@ export class InputHandler { } // Throttling: Limit high-frequency events to ~60fps (16ms) - if (msg.type === 'move' || msg.type === 'scroll') { + if (msg.type === 'move') { const now = Date.now(); - if (now - this.lastEventTime < 16) { + if (now - this.lastMoveTime < 16) { + this.pendingMove = msg; + if (!this.moveTimer) { + this.moveTimer = setTimeout(() => { + this.moveTimer = null; + if (this.pendingMove) { + const pending = this.pendingMove; + this.pendingMove = null; + this.handleMessage(pending); + } + }, 16); + } + return; + } + this.lastMoveTime = now; + } else if (msg.type === 'scroll') { + const now = Date.now(); + if (now - this.lastScrollTime < 16) { + this.pendingScroll = msg; + if (!this.scrollTimer) { + this.scrollTimer = setTimeout(() => { + this.scrollTimer = null; + if (this.pendingScroll) { + const pending = this.pendingScroll; + this.pendingScroll = null; + this.handleMessage(pending); + } + }, 16); + } return; } - this.lastEventTime = now; + this.lastScrollTime = now; } switch (msg.type) { From 77bb691e43cca554a18896549ca18ac5e78851e3 Mon Sep 17 00:00:00 2001 From: Aniket Date: Sun, 15 Feb 2026 01:48:17 +0530 Subject: [PATCH 4/4] code rabbit suggestions --- src/server/InputHandler.ts | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/server/InputHandler.ts b/src/server/InputHandler.ts index ba78bf5..1c6fc9c 100644 --- a/src/server/InputHandler.ts +++ b/src/server/InputHandler.ts @@ -5,7 +5,7 @@ export interface InputMessage { type: 'move' | 'click' | 'scroll' | 'key' | 'text' | 'zoom' | 'combo'; dx?: number; dy?: number; - button?: 'left' | 'right'' | 'middle'; + button?: 'left' | 'right' | 'middle'; press?: boolean; key?: string; keys?: string[]; @@ -81,17 +81,21 @@ export class InputHandler { case 'move': if (msg.dx !== undefined && msg.dy !== undefined) { const currentPos = await mouse.getPosition(); - - await mouse.setPosition(new Point( - currentPos.x + msg.dx, - currentPos.y + msg.dy - )); + await mouse.setPosition( + new Point(currentPos.x + msg.dx, currentPos.y + msg.dy) + ); } break; case 'click': if (msg.button) { - const btn = msg.button === 'left' ? Button.LEFT : msg.button === 'right' ? Button.RIGHT : Button.MIDDLE; + const btn = + msg.button === 'left' + ? Button.LEFT + : msg.button === 'right' + ? Button.RIGHT + : Button.MIDDLE; + if (msg.press) { await mouse.pressButton(btn); } else { @@ -128,15 +132,18 @@ export class InputHandler { case 'zoom': if (msg.delta !== undefined && msg.delta !== 0) { - const sensitivityFactor = 0.5; + const sensitivityFactor = 0.5; const MAX_ZOOM_STEP = 5; const scaledDelta = Math.sign(msg.delta) * - Math.min(Math.abs(msg.delta) * sensitivityFactor, MAX_ZOOM_STEP); + Math.min( + Math.abs(msg.delta) * sensitivityFactor, + MAX_ZOOM_STEP + ); const amount = -scaledDelta; - + await keyboard.pressKey(Key.LeftControl); try { await mouse.scrollDown(amount); @@ -150,6 +157,7 @@ export class InputHandler { if (msg.key) { console.log(`Processing key: ${msg.key}`); const nutKey = KEY_MAP[msg.key.toLowerCase()]; + if (nutKey !== undefined) { await keyboard.type(nutKey); } else if (msg.key.length === 1) { @@ -163,9 +171,11 @@ export class InputHandler { case 'combo': if (msg.keys && msg.keys.length > 0) { const nutKeys: (Key | string)[] = []; + for (const k of msg.keys) { const lowerKey = k.toLowerCase(); const nutKey = KEY_MAP[lowerKey]; + if (nutKey !== undefined) { nutKeys.push(nutKey); } else if (lowerKey.length === 1) { @@ -185,7 +195,7 @@ export class InputHandler { try { for (const k of nutKeys) { - if (typeof k === "string") { + if (typeof k === 'string') { await keyboard.type(k); } else { await keyboard.pressKey(k); @@ -193,7 +203,9 @@ export class InputHandler { } } - await new Promise(resolve => setTimeout(resolve, 10)); + await new Promise(resolve => + setTimeout(resolve, 10) + ); } finally { for (const k of pressedKeys.reverse()) { await keyboard.releaseKey(k);