1+ import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime" ;
12import { resolveBrowserNavigationProxyMode } from "../browser-proxy-mode.js" ;
23import {
34 BrowserProfileUnavailableError ,
@@ -12,13 +13,7 @@ import {
1213import type { BrowserRouteContext , ProfileContext } from "../server-context.js" ;
1314import { resolveTargetIdFromTabs } from "../target-id.js" ;
1415import type { BrowserRequest , BrowserResponse , BrowserRouteRegistrar } from "./types.js" ;
15- import {
16- asyncBrowserRoute ,
17- getProfileContext ,
18- jsonError ,
19- toNumber ,
20- toStringOrEmpty ,
21- } from "./utils.js" ;
16+ import { asyncBrowserRoute , getProfileContext , jsonError , toStringOrEmpty } from "./utils.js" ;
2217
2318function resolveTabsProfileContext (
2419 req : BrowserRequest ,
@@ -136,6 +131,27 @@ function readOptionalTabLabel(body: unknown): string | undefined {
136131 return label || undefined ;
137132}
138133
134+ function readTabIndex (
135+ res : BrowserResponse ,
136+ body : unknown ,
137+ opts ?: { required ?: boolean } ,
138+ ) : number | null | undefined {
139+ const record = body && typeof body === "object" ? ( body as Record < string , unknown > ) : { } ;
140+ if ( ! Object . hasOwn ( record , "index" ) ) {
141+ if ( opts ?. required ) {
142+ jsonError ( res , 400 , "index is required" ) ;
143+ return null ;
144+ }
145+ return undefined ;
146+ }
147+ const index = parseStrictNonNegativeInteger ( record . index ) ;
148+ if ( index === undefined ) {
149+ jsonError ( res , 400 , "index must be a non-negative integer" ) ;
150+ return null ;
151+ }
152+ return index ;
153+ }
154+
139155async function runTabTargetMutation ( params : {
140156 req : BrowserRequest ;
141157 res : BrowserResponse ;
@@ -269,7 +285,6 @@ export function registerBrowserTabRoutes(app: BrowserRouteRegistrar, ctx: Browse
269285 "/tabs/action" ,
270286 asyncBrowserRoute ( async ( req , res ) => {
271287 const action = toStringOrEmpty ( ( req . body as { action ?: unknown } ) ?. action ) ;
272- const index = toNumber ( ( req . body as { index ?: unknown } ) ?. index ) ;
273288
274289 await withTabsProfileRoute ( {
275290 req,
@@ -320,6 +335,10 @@ export function registerBrowserTabRoutes(app: BrowserRouteRegistrar, ctx: Browse
320335 if ( ! ( await ensureBrowserRunning ( profileCtx , res ) ) ) {
321336 return ;
322337 }
338+ const index = readTabIndex ( res , req . body ) ;
339+ if ( index === null ) {
340+ return ;
341+ }
323342 const tabs = await profileCtx . listTabs ( ) ;
324343 const target = resolveIndexedTab ( tabs , index ) ;
325344 if ( ! target ) {
@@ -330,8 +349,9 @@ export function registerBrowserTabRoutes(app: BrowserRouteRegistrar, ctx: Browse
330349 }
331350
332351 if ( action === "select" ) {
333- if ( typeof index !== "number" ) {
334- return jsonError ( res , 400 , "index is required" ) ;
352+ const index = readTabIndex ( res , req . body , { required : true } ) ;
353+ if ( index === null || index === undefined ) {
354+ return ;
335355 }
336356 if ( ! ( await ensureBrowserRunning ( profileCtx , res ) ) ) {
337357 return ;
0 commit comments