Sicherheitsrunde II: PTY-Label, Tool-Grenzen, atomare Schreibvorgänge
- term_start nur noch für das eigene term-<projekt>-Fenster — das (abgelöste) Panel-Fenster kann keine Shell mehr starten und beschreiben. Die Tauri-ACL greift für App-Commands nachweislich nicht (kein __app-acl__-Manifest, Prüfung gegen tauri 2.11.5); die Label-Prüfung ist damit die Schranke, nicht deren Verdopplung. - archive_panel verliert das dir-Argument: Archiv-Home samt dauerhafter Rechtevergabe (additionalDirectories + Edit-Allow) setzt nur noch die UI mit Nutzer-Dialog, kein Tool-Argument des Modells. - write_panel(path) liest nur noch aus Projekt-, Arbeits- und Archiv-Ordnern (canonicalize, symlink-fest), reguläre Dateien bis 2 MB mit hartem Byte-Cap — der promptfreie Weg umgeht das Read-Permission-Modell von Claude Code nicht mehr. - write_atomic (temp + rename) für alle JSON-Config-Schreiber: Projekt- Config, .claude/settings.json, Registry, App-Settings, pool.json, Pool-settings.json, claudes .claude.json, Todo-Hook. - write_secret_file: create_new mit 0600 statt schreiben-und-abdichten; kein umask-Fenster, Symlinks werden nicht gefolgt. - PTY-Umgebung: geerbte ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN entfernt. - panel_file & Geschwister prüfen die Projekt-ID (zweite Linie). - Befehlskacheln filtern Bidi-/Zero-Width-Zeichen aus Anzeige und Zwischenablage; der Lösch-Abgleich behält den Originaltext.
This commit is contained in:
+15
-3
@@ -7,6 +7,13 @@
|
||||
|
||||
import { writeText } from "@tauri-apps/plugin-clipboard-manager";
|
||||
|
||||
|
||||
/// Entfernt Bidi- und Zero-Width-Steuerzeichen (U+200B–200F, U+202A–202E,
|
||||
/// U+2060–2064, U+2066–2069, U+FEFF) aus Befehlstexten.
|
||||
function stripInvisibles(s: string): string {
|
||||
return s.replace(/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u2069\uFEFF]/g, "");
|
||||
}
|
||||
|
||||
interface CommandEntry {
|
||||
cmd: string;
|
||||
note?: string;
|
||||
@@ -106,7 +113,7 @@ export function initCommandsView(
|
||||
all.className = "cmd-all";
|
||||
all.textContent = "Alle kopieren";
|
||||
all.addEventListener("click", async () => {
|
||||
await writeText(cmds.map((c) => c.cmd).join("\n"));
|
||||
await writeText(cmds.map((c) => stripInvisibles(c.cmd)).join("\n"));
|
||||
flash(all, "copied");
|
||||
});
|
||||
head.append(all);
|
||||
@@ -114,13 +121,18 @@ export function initCommandsView(
|
||||
block.append(head);
|
||||
|
||||
cmds.forEach((entry, j) => {
|
||||
// Unsichtbare Steuerzeichen (Bidi, Zero-Width) aus Anzeige UND
|
||||
// Kopie halten — sonst sieht der Nutzer einen anderen Befehl, als
|
||||
// die Zwischenablage enthält. Der Lösch-Abgleich läuft weiter über
|
||||
// den Original-String.
|
||||
const visible = stripInvisibles(entry.cmd);
|
||||
const tile = document.createElement("div");
|
||||
tile.className = "cmd-tile";
|
||||
const body = document.createElement("div");
|
||||
body.className = "cmd-body";
|
||||
const cmd = document.createElement("div");
|
||||
cmd.className = "cmd-text";
|
||||
cmd.textContent = entry.cmd;
|
||||
cmd.textContent = visible;
|
||||
body.append(cmd);
|
||||
if (entry.note) {
|
||||
const note = document.createElement("div");
|
||||
@@ -128,7 +140,7 @@ export function initCommandsView(
|
||||
note.textContent = entry.note;
|
||||
body.append(note);
|
||||
}
|
||||
tile.append(body, copyBtn(() => entry.cmd), deleteBtn(() => onDelete(i, j, entry.cmd)));
|
||||
tile.append(body, copyBtn(() => visible), deleteBtn(() => onDelete(i, j, entry.cmd)));
|
||||
block.append(tile);
|
||||
});
|
||||
container.append(block);
|
||||
|
||||
Reference in New Issue
Block a user