Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Java/Openclaw/src/agents/sandbox/   (KI Agentensystem Version 22©)  Datei vom 26.3.2026 mit Größe 6 kB image not shown  

Quelle  remote-fs-bridge.test.ts

  Sprache: JAVA
 

Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import { spawnSync } from "node:child_process";
import fs from "node:fs/promises";
import path from "node:path";
import { describe, expect, it } from "vitest";
import { SANDBOX_PINNED_MUTATION_PYTHON } from "./fs-bridge-mutation-helper.js";
import { createSandbox } from "./fs-bridge.test-helpers.js";
import {
  createRemoteShellSandboxFsBridge,
  type RemoteShellSandboxHandle,
} from "./remote-fs-bridge.js";

function createLocalRemoteRuntime(params: {
  remoteWorkspaceDir: string;
  remoteAgentWorkspaceDir: string;
}) {
  const calls: Array<Parameters<RemoteShellSandboxHandle["runRemoteShellScript"]>[0]> = [];
  const runtime: RemoteShellSandboxHandle = {
    remoteWorkspaceDir: params.remoteWorkspaceDir,
    remoteAgentWorkspaceDir: params.remoteAgentWorkspaceDir,
    runRemoteShellScript: async (command) => {
      calls.push(command);
      const result = command.script.includes("python3 /dev/fd/3 \"$@\" 3<<'PY'")
        ? spawnSync("python3", ["-c", SANDBOX_PINNED_MUTATION_PYTHON, ...(command.args ?? [])], {
            input: command.stdin,
            encoding: "buffer",
            stdio: ["pipe", "pipe", "pipe"],
          })
        : spawnSync("sh", ["-c", command.script, "openclaw-sandbox-fs", ...(command.args ?? [])], {
            input: command.stdin,
            encoding: "buffer",
            stdio: ["pipe", "pipe", "pipe"],
          });
      const stdout = Buffer.isBuffer(result.stdout)
        ? result.stdout
        : Buffer.from(result.stdout ?? []);
      const stderr = Buffer.isBuffer(result.stderr)
        ? result.stderr
        : Buffer.from(result.stderr ?? []);
      const code = result.status ?? (result.signal ? 128 : 1);
      if (result.error) {
        throw result.error;
      }
      if (code !== 0 && !command.allowFailure) {
        throw Object.assign(
          new Error(stderr.toString("utf8").trim() || `shell exited with code ${code}`),
          { code, stdout, stderr },
        );
      }
      return { stdout, stderr, code };
    },
  };
  return { calls, runtime };
}

function createWorkspaceReadBridge(workspaceDir: string) {
  const { runtime } = createLocalRemoteRuntime({
    remoteWorkspaceDir: workspaceDir,
    remoteAgentWorkspaceDir: workspaceDir,
  });
  return createRemoteShellSandboxFsBridge({
    sandbox: createSandbox({
      workspaceDir,
      agentWorkspaceDir: workspaceDir,
    }),
    runtime,
  });
}

describe("remote sandbox fs bridge", () => {
  it.runIf(process.platform !== "win32")(
    "reads files with the pinned mutation helper",
    async () => {
      await withTempDir("openclaw-remote-fs-bridge-", async (stateDir) => {
        const workspaceDir = path.join(stateDir, "workspace");
        await fs.mkdir(workspaceDir, { recursive: true });
        await fs.writeFile(path.join(workspaceDir, "note.txt"), "hello", "utf8");

        const { calls, runtime } = createLocalRemoteRuntime({
          remoteWorkspaceDir: workspaceDir,
          remoteAgentWorkspaceDir: workspaceDir,
        });
        const bridge = createRemoteShellSandboxFsBridge({
          sandbox: createSandbox({
            workspaceDir,
            agentWorkspaceDir: workspaceDir,
          }),
          runtime,
        });

        await expect(bridge.readFile({ filePath: "note.txt" })).resolves.toEqual(
          Buffer.from("hello"),
        );
        expect(calls).toHaveLength(1);
        expect(calls[0]?.args?.[0]).toBe("read");
        expect(calls[0]?.script).toContain("python3 /dev/fd/3 \"$@\" 3<<'PY'");
        expect(calls[0]?.script).toContain("read_file(parent_fd, basename)");
        expect(calls[0]?.script).not.toContain('cat -- "$1"');
      });
    },
  );

  it.runIf(process.platform !== "win32")(
    "rejects mount-root reads before invoking the mutation helper",
    async () => {
      await withTempDir("openclaw-remote-fs-bridge-", async (stateDir) => {
        const workspaceDir = path.join(stateDir, "workspace");
        await fs.mkdir(workspaceDir, { recursive: true });

        const { calls, runtime } = createLocalRemoteRuntime({
          remoteWorkspaceDir: workspaceDir,
          remoteAgentWorkspaceDir: workspaceDir,
        });
        const bridge = createRemoteShellSandboxFsBridge({
          sandbox: createSandbox({
            workspaceDir,
            agentWorkspaceDir: workspaceDir,
          }),
          runtime,
        });

        await expect(bridge.readFile({ filePath: "." })).rejects.toThrow(
          /Invalid sandbox entry target/,
        );
        expect(calls).toHaveLength(0);
      });
    },
  );

  it.runIf(process.platform !== "win32")("rejects symlink escapes while reading", async () => {
    await withTempDir("openclaw-remote-fs-bridge-", async (stateDir) => {
      const workspaceDir = path.join(stateDir, "workspace");
      const outsideDir = path.join(stateDir, "outside");
      await fs.mkdir(workspaceDir, { recursive: true });
      await fs.mkdir(outsideDir, { recursive: true });
      await fs.writeFile(path.join(outsideDir, "secret.txt"), "classified", "utf8");
      await fs.symlink(path.join(outsideDir, "secret.txt"), path.join(workspaceDir, "link.txt"));

      const bridge = createWorkspaceReadBridge(workspaceDir);

      await expect(bridge.readFile({ filePath: "link.txt" })).rejects.toThrow(
        /symbolic links|too many levels|ELOOP/i,
      );
    });
  });

  it.runIf(process.platform !== "win32")(
    "rejects final-component symlinks even when they stay inside the workspace",
    async () => {
      await withTempDir("openclaw-remote-fs-bridge-", async (stateDir) => {
        const workspaceDir = path.join(stateDir, "workspace");
        await fs.mkdir(workspaceDir, { recursive: true });
        await fs.writeFile(path.join(workspaceDir, "note.txt"), "hello", "utf8");
        await fs.symlink("note.txt", path.join(workspaceDir, "link.txt"));

        const bridge = createWorkspaceReadBridge(workspaceDir);

        await expect(bridge.readFile({ filePath: "link.txt" })).rejects.toThrow(
          /symbolic links|too many levels|ELOOP/i,
        );
      });
    },
  );
});

async function withTempDir<T>(prefix: string, run: (stateDir: string) => Promise<T>): Promise<T> {
  const stateDir = await fs.mkdtemp(path.join(process.env.TMPDIR ?? "/tmp", prefix));
  try {
    return await run(stateDir);
  } finally {
    await fs.rm(stateDir, { recursive: true, force: true });
  }
}

¤ Dauer der Verarbeitung: 0.26 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.