Skip to content

< all problems54 · Level 04, Tool Calling

Keep the File Tools Inside the Workspace

easy · implement · Tool Calling

A coding agent's read_file tool takes whatever path the model asks for. Yesterday it asked for ../../.aws/credentials, because a README said the config lived there, and got it.

Implement safe_join(root, path). root is the workspace directory as a POSIX path (/repo). Return the resolved path as a string, or raise PathEscape (provided) when the request would leave the workspace. Resolve the way a filesystem would, without touching one:

  • Split on /, and treat a backslash as a separator too.
  • Drop empty segments and ., so src//./app.py is src/app.py.
  • .. steps up one segment. Stepping up from the workspace root is an escape.
  • An absolute path (/etc/passwd) or a drive letter (C:) is an escape, even when it starts with root.
  • A leading ~ is an escape.
  • A null byte anywhere is an escape.

The result is root followed by the surviving segments. An empty request, or ., resolves to root itself.

read_file(files, path) in the fixtures calls your function before it looks anything up.