diff --git a/test/rt/x86-64-linux/zreadlink0.v3 b/test/rt/x86-64-linux/zreadlink0.v3 new file mode 100644 index 000000000..0086233ac --- /dev/null +++ b/test/rt/x86-64-linux/zreadlink0.v3 @@ -0,0 +1,55 @@ +def LOOKUP_SYMLINK_FOLLOW = 1; // flag indicating should follow symlinks +def SYS_readlink = 0x59; // Linux system call to read a symlink +def PATH_MAX = 15; // maximum length of a path +def EINVAL = 22; // errno for invalid argument +def ENOENT = 2; // errno for no entry + + +// Resolves a path without following symlinks, ensuring it stays within the sandbox. +def resolve_path_without_link(path: string) -> (string, int) { + return (path, 0); +} + +// Main function to resolve a path with an option to follow symlinks, ensuring it stays within the sandbox. +def resolve_path0(fdpath: string, path: string, flags: i32) -> (string, int) { + var result = resolve_path_without_link(path); + if (result.1 != 0) return (result.0, result.1); + var normalized = result.0; + + if ((flags & LOOKUP_SYMLINK_FOLLOW) == LOOKUP_SYMLINK_FOLLOW) { + var buffer = string.new(PATH_MAX); + var t = Linux.syscall(SYS_readlink, (Pointer.atContents(normalized), Pointer.atContents(buffer), PATH_MAX)); + + if (t.0 < 0) return (normalized, 0); + return (buffer, 0); // If the path is a symlink, return it + } + return (normalized, 0); +} + +def main() -> int { + System.puts("##+resolve_path\n"); + var expected = "/foo/test_path"; + var result = resolve_path0("/foo", "/foo/test_path", 0).0; + if (expected == null) { + System.puts("##-fail, expected is null"); + } else if (result == null) { + System.puts("##-fail, result is null"); + } else if (!equal(expected, result)) { + System.puts("##-fail, got: "); + System.puts(result); + } else { + System.puts("##-ok\n"); + return 0; + } + return 1; +} + +// Compare two strings for equality. +def equal(arr1: string, arr2: string) -> bool { + if (arr1 == arr2) return true; + if (arr1.length != arr2.length) return false; + for (i < arr1.length) { + if (arr1[i] != arr2[i]) return false; + } + return true; +} diff --git a/test/rt/x86-64-linux/zreadlink0.v3.exit b/test/rt/x86-64-linux/zreadlink0.v3.exit new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/test/rt/x86-64-linux/zreadlink0.v3.exit @@ -0,0 +1 @@ +0 diff --git a/test/rt/x86-64-linux/zreadlink0.v3.out b/test/rt/x86-64-linux/zreadlink0.v3.out new file mode 100644 index 000000000..78462218d --- /dev/null +++ b/test/rt/x86-64-linux/zreadlink0.v3.out @@ -0,0 +1,2 @@ +##+resolve_path +##-ok