For example, the `tainted` string `user@freeradius.org/..` will turn into the filename `user@freeradius.org_2f..`. This operation renders the filename "safe" for operations on the local file system. It is not possible for `tainted` data to create files, or to perform directory traversal attacks.
+== %file.escape(_string_)
+
+.Return: _string_
+
+This function returns an escaped or "safe" version of the input string.
+
+In some cases, as when using `%exec(...)`, it is impossible to determine which arguments are filenames, and which are simple strings. This function allows the server to safely pass in a filename to external programs.
+
+The returned filename is guaranteed to be safe to use. Any portion of the filename which is taken from a "safe" source (i.e. configuration files, etc. controlled by an administator) is used as-is. Any portion of the filename which is taken from an "unsafe" source (i.e. network apckets) is escaped. The result is that characters like `/` in unsafe inputs cannot be used to perform directory traversal attacks.
+
+.Safely pass a filename to `%exec(...)`
+====
+[source,unlang]
+----
+&filename = "${logdir}/" + %file.escape(%{User-Name})
+
+%exec("/bin/rm", %{filename})
+----
+====
+
+
== %file.exists(_string_)
.Return: _bool_
xlat_expr %file.exists('src/tests/xlat/file/no-such-file')
match no
+
+xlat_expr "foo/bar/" + %file.escape(%taint('..baz'))
+match foo/bar/_x2e_x2ebaz
+
+#
+# Can't do expressions as function arguments
+#
+xlat_expr %file.escape('foo/bar' + "/baz")
+match ERROR offset 34 'Unexpected text after argument 1'