我正在尝试检查路径是否比当前目录指向“上”。 示例:
我在"./"
比方说,当前目录包含一个名为“文件夹”的文件夹
我想检查cd "./folder/../../"
是否将我引到“ ./”之外。
在这种情况下,它会回答我对。
这是将我的程序绑定到其执行文件夹(我希望它执行ls,但永远不在外面)。
答案 0 :(得分:4)
POSIX.1-2001定义了realpath(3):
#include <limits.h> #include <stdlib.h> char *realpath(const char *path, char *resolved_path);
realpath()
扩展所有符号链接并解析对以path命名的以空字符结尾的字符串中的/./
,/../
和其他'/'
字符的引用,以产生规范化的绝对路径名。结果路径名以空终止的字符串形式存储,最多PATH_MAX
个字节,存储在resolved_path
指向的缓冲区中。结果路径将没有符号链接,/./
或/../
组件。
您可以将规范化路径与当前目录进行比较,看看前者是否为后者的后代。
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool is_inside(const char *parent, const char *child) {
char *abs_parent = realpath(parent, NULL);
if (!abs_parent) { perror(parent); exit(EXIT_FAILURE); }
char *abs_child = realpath(child, NULL);
if (!abs_child) { perror(child); exit(EXIT_FAILURE); }
size_t parent_len = strlen(abs_parent);
size_t child_len = strlen(abs_child);
bool result = strncmp(abs_parent, abs_child, parent_len) == 0 &&
(child_len == parent_len || abs_child[parent_len] == '/');
free(abs_parent);
free(abs_child);
return result;
}
int main(int argc, char **argv) {
if (argc != 3) {
fprintf(stderr, "usage: %s <parent> <child>\n", argv[0]);
return 1;
}
printf("%s\n", is_inside(argv[1], argv[2]) ? "yes" : "no");
return 0;
}
请注意,这仅在路径存在时有效。
答案 1 :(得分:0)
伪代码:
pwd
)
暂时没有完成C
,但这是bash
中相同逻辑的快速攻克
$: pwd
/tmp/sandbox
$: cur=$(pwd)
$: cd ./folder/../../
$: pwd
/tmp
$: pwd|grep "^$cur" && echo in || echo out
out
$: cd -
/tmp/sandbox
$: pwd|grep "^$cur" && echo in || echo out
/tmp/sandbox
in
$: cd ./folder/
$: pwd|grep "^$cur" && echo in || echo out
/tmp/sandbox/folder
in
答案 2 :(得分:0)
您可以计算出与“ ..”,“。” 、:相匹配的组件数:
for (p = strtok(path, "/"); p; p = strtok(NULL, "/")) {
if (strcmp(p, "..") == 0) {
counters[Back]++;
} else if (strcmp(p, ".") == 0) {
counters[Self]++;
} else if (*p) { /* ignore /// runs */
counters[Forw]++;
}
escaped |= (counters[Back] > counters[Forw]);
}
转义捕获路径是否尝试从当前工作目录下的树中转义。可能值得用特殊的大小写将“ /”作为转义符。
还有其他一些方法可以解码绝对路径空间,但是可能导致超范围(imho,一种常见的系统故障模式)。我以所有者的身份,可能希望您的程序至少以有限的方式接受逃避名称空间的路径名。符号链接对此非常有效,不需要特殊的管理控制等。如果您的程序阻止这种配置,那么它的实用程序就会减少。