hakojs
Version:
A secure, embeddable JavaScript engine that runs untrusted code inside WebAssembly sandboxes with fine-grained permissions and resource limits
206 lines • 7.97 kB
TypeScript
/**
* interrupt-helpers.ts - Helper functions for creating interrupt handlers
*
* This module provides utilities for creating and managing interrupt handlers
* that can terminate long-running JavaScript operations in the Hako runtime.
* Interrupt handlers are essential for preventing infinite loops, excessive
* CPU usage, and memory exhaustion by untrusted code.
*/
import type { InterruptHandler } from "../etc/types";
/**
* Creates an interrupt handler that terminates execution after a specified time deadline.
*
* This is useful for imposing a maximum execution time on JavaScript code, preventing
* long-running operations from blocking the system. The deadline is calculated as
* the current time plus the specified milliseconds.
*
* @param deadlineMs - The maximum execution time in milliseconds
* @returns An interrupt handler function that will return true when the deadline is reached
*
* @example
* ```typescript
* // Create a handler that interrupts after 5 seconds
* const handler = shouldInterruptAfterDeadline(5000);
* runtime.enableInterruptHandler(handler);
*
* // This will be interrupted if it runs for more than 5 seconds
* context.evaluateScript(`
* while(true) {
* // Infinite loop that will be interrupted
* }
* `);
* ```
*/
export declare function shouldInterruptAfterDeadline(deadlineMs: number): InterruptHandler;
/**
* Creates an interrupt handler that terminates execution after a certain number of operations.
*
* This provides a more deterministic approach to limiting execution compared to
* time-based limits. Each time the handler is called by the runtime (typically once
* per operation or small block of operations), it increments a counter and interrupts
* when the counter exceeds the specified maximum.
*
* @param maxSteps - The maximum number of operations to allow before interrupting
* @returns An interrupt handler function that will return true after the specified number of steps
*
* @example
* ```typescript
* // Create a handler that interrupts after 1 million operations
* const handler = shouldInterruptAfterSteps(1000000);
* runtime.enableInterruptHandler(handler);
*
* // This will be interrupted after approximately 1 million operations
* context.evaluateScript(`
* let counter = 0;
* while(true) {
* counter++;
* }
* `);
* ```
*/
export declare function shouldInterruptAfterSteps(maxSteps: number): InterruptHandler;
/**
* Creates an interrupt handler that terminates execution if memory usage exceeds a specified limit.
*
* This helps prevent memory-intensive scripts from exhausting system resources.
* To minimize performance impact, memory usage is only checked periodically rather
* than on every operation.
*
* @param maxMemoryBytes - Maximum memory usage in bytes before interrupting
* @param checkIntervalSteps - How often to check memory usage (every N operations), defaults to 1000
* @returns An interrupt handler function that will return true when memory usage exceeds the limit
*
* @example
* ```typescript
* // Create a handler that interrupts if memory usage exceeds 100MB
* const handler = shouldInterruptAfterMemoryUsage(100 * 1024 * 1024);
* runtime.enableInterruptHandler(handler);
*
* // This will be interrupted if it allocates more than 100MB
* context.evaluateScript(`
* const arrays = [];
* while(true) {
* arrays.push(new Uint8Array(1024 * 1024)); // Allocate 1MB per iteration
* }
* `);
* ```
*/
export declare function shouldInterruptAfterMemoryUsage(maxMemoryBytes: number, checkIntervalSteps?: number): InterruptHandler;
/**
* Creates a composite interrupt handler that combines multiple interrupt conditions.
*
* This function allows combining several interrupt handlers, such as time limits,
* step limits, and memory limits. The resulting handler will interrupt execution
* if ANY of the provided handlers returns true.
*
* @param handlers - Array of interrupt handlers to combine
* @returns A combined interrupt handler function
*
* @example
* ```typescript
* // Create a handler that interrupts after 5 seconds OR 1 million steps
* const timeHandler = shouldInterruptAfterDeadline(5000);
* const stepHandler = shouldInterruptAfterSteps(1000000);
* const combinedHandler = combineInterruptHandlers(timeHandler, stepHandler);
*
* runtime.enableInterruptHandler(combinedHandler);
* ```
*/
export declare function combineInterruptHandlers(...handlers: InterruptHandler[]): InterruptHandler;
/**
* Creates an interrupt handler with multiple resource limits in a single call.
*
* This is a convenience function that creates and combines appropriate interrupt
* handlers based on the specified options. You can limit execution time, memory
* usage, and/or operation count with a single function call.
*
* @param options - Configuration options for resource limits
* @param options.maxTimeMs - Optional maximum execution time in milliseconds
* @param options.maxMemoryBytes - Optional maximum memory usage in bytes
* @param options.maxSteps - Optional maximum number of operations
* @param options.memoryCheckInterval - Optional interval for memory checks (default: 1000)
* @returns A combined interrupt handler function
*
* @example
* ```typescript
* // Create a handler with multiple limits
* const handler = createResourceLimitedInterruptHandler({
* maxTimeMs: 5000, // 5 seconds max
* maxMemoryBytes: 100_000_000, // 100MB max
* maxSteps: 10_000_000, // 10 million operations max
* });
*
* runtime.enableInterruptHandler(handler);
* ```
*/
export declare function createResourceLimitedInterruptHandler(options: {
maxTimeMs?: number;
maxMemoryBytes?: number;
maxSteps?: number;
memoryCheckInterval?: number;
}): InterruptHandler;
/**
* A pausable interrupt handler that can be enabled/disabled at runtime.
*
* This class wraps an existing interrupt handler and provides methods to
* temporarily pause and resume interruption. This is useful for scenarios
* where you need to disable interruption during critical sections of code,
* then re-enable it afterward.
*
* @example
* ```typescript
* // Create a pausable handler with a 5-second time limit
* const baseHandler = shouldInterruptAfterDeadline(5000);
* const pausableHandler = new PausableInterruptHandler(baseHandler);
*
* // Enable the pausable handler
* runtime.enableInterruptHandler(pausableHandler.interruptHandler);
*
* // Later, temporarily pause interruption
* pausableHandler.pause();
*
* // Execute critical code without interruption
* context.evaluateScript("");
*/
export declare class PausableInterruptHandler {
private handler;
private isPaused;
/**
* Creates a new pausable interrupt handler.
*
* @param baseHandler - The underlying interrupt handler to wrap
*/
constructor(baseHandler: InterruptHandler);
/**
* The interrupt handler function to pass to the runtime.
*
* Use this property when calling `runtime.enableInterruptHandler()`.
*
* @param runtime - The Hako runtime instance
* @param context - The VM context
* @param opaque - Opaque data passed to the handler enable call
* @returns Boolean indicating whether execution should be interrupted
*/
interruptHandler: InterruptHandler;
/**
* Pauses the interrupt handler.
*
* While paused, the handler will not interrupt execution regardless of
* resource usage or other conditions.
*/
pause(): void;
/**
* Resumes the interrupt handler.
*
* After resuming, the handler will again interrupt execution based on
* its underlying conditions.
*/
resume(): void;
/**
* Toggles the paused state of the interrupt handler.
*
* @returns The new paused state (true if now paused, false if now active)
*/
toggle(): boolean;
}
//# sourceMappingURL=interrupt-helpers.d.ts.map