Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ curl -fsSL https://bend-lang.com/install.sh | sh
This `bend` ignores a project's `bunfig.toml` and `.env`; `bun bend2/main.ts`
from a checkout reads them, so check untrusted code with `bend`.

Compilation rejects `-o` paths that match a program input by path or file
identity, including symlinks and hard links.

### 2. Tell your agent to use Bend:

Add this to your `AGENTS.md`:
Expand Down
13 changes: 8 additions & 5 deletions bend2/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,9 @@ async function cli_file(args: string[]): Promise<void> {
return;
}
const ins = new Set([...seen.keys(), ...Object.values(book.tlds).flatMap((t) =>
t.$ === "Def" && t.i !== undefined ? t.i.map(path_real) : [])]);
t.$ === "Def" && t.i !== undefined ? t.i : [])].map(path_id)).add("");
for (const out of outs) {
const at = path_real(out);
if (ins.has(at) || (fs.existsSync(at) && fs.statSync(at).isDirectory())) {
if (ins.has(path_id(out))) {
cli_fail("-o " + out + " is a file the program reads, or a directory");
}
cli_emit(book, out);
Expand Down Expand Up @@ -356,8 +355,12 @@ async function cli_checkup(file: string): Promise<void> {
}
}

function path_real(p: string): string {
return fs.existsSync(p) ? fs.realpathSync(p) : path.resolve(p);
// A path names a file by device and inode, so links to one file agree, and
// every directory is "".
function path_id(p: string): string {
const s = fs.statSync(p, { bigint: true, throwIfNoEntry: false });
return s === undefined ? path.resolve(p)
: s.isDirectory() ? "" : s.dev + ":" + s.ino;
}

function cli_emit(book: Bend.Book, out: string): void {
Expand Down
6 changes: 6 additions & 0 deletions gates/ping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,12 @@ try {
&& page.err.includes("page.ts:1:") && !page.err.includes("Bun v"));
const bad_file = path.join(TMP, "bad.bend");
const sum_file = path.join(TMP, "sum.bend");
const sum_alias = path.join(TMP, "sum-alias.js");
fs.linkSync(sum_file, sum_alias);
const linked_out = await bend([sum_file, "-o", sum_alias]);
const linked_run = await bend([sum_file]);
check("an output hard link cannot destroy its input",
linked_out.code === 1 && linked_run.code === 0 && linked_run.out === "5n\n");
const unsafe_file = path.join(TMP, "unsafe.bend");
const checkup = path.join(TMP, "checkup.bend");
const good_checkup = path.join(TMP, "good_checkup.bend");
Expand Down