本次为了方便展示和调试,并没有将代买写入到真实的运行环境,而是单独写了一个test程序,
使用的思路主要是回溯。首先记录本次的开始位置,
情况一:如果本次得到内容时“./”,回溯到本次开始匹配的位置即可。
情况二:如果本次得到的内容是"/",回溯到本次开始匹配的位置即可。
情况三: 如果本次的到的内容时“../",首先回溯到本次开始匹配的位置,并且删除上一级目录
其他情况: 直接写入本次匹配的值。开始下一次匹配。
一下为程序代码,本code只经过本人的简单测试,可能会存在漏洞。希望大家在查看的同时,写出更好的代码。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
/*对url中的相对路径的符合进行处理。
* 从url中移除 "/../", "//", "/./" 。
*
* /reage/.. 真实路径为 /
* /reage/../reage1 真实路径为 /reage1
* /reage/./reage1 真实路径为 /reage/reage1
* /reage//reage1 真实路径为 /reage/reage
*
*
*/
int buffer_path_simplify(char *dest, const char *src)
{
int count;
char c;
/*
start保存结果路径的开始位置。
slash本次配皮的开始位置,
walk正在匹配的字符
out将要写入的结果的位置
*/
char *start, *slash, *walk, *out;
char pre; //当前匹配的前一个字符
if (src == NULL || dest == NULL)
return -1;
walk = src;
start = dest;
out = dest;
slash = dest;
while (*walk == ' ') {
walk++;
}
pre = *(walk++);
c = *(walk++);
if (pre != '/') {
*(out++) = '/';
}
*(out++) = pre;
if (pre == '\0') {
*out = 0;
return 0;
}
while (1) {
// '/'表示本次匹配的结束,'\0'表示整个过程的结束
if (c == '/' || c == '\0') {
//计算本次共匹配到的字符 即使'/'与'/'的距离
count = out - slash;
//说明本次匹配为../需要删除前面的目录
if (count == 3 && pre == '.') {
//首先回到本次匹配的开始,即使../的一个点的位置,
out = slash;
//回溯到前面的一个目录,只要前面不是根目录
if (out > start) {
out--;
while (out > start && *out != '/') {
out--;
}
}
if (c == '\0')
out++;
} else if (count == 1 || pre == '.') {
//本次匹配为“./”只要删除掉就可。即使回到本次开始匹配的位置
out = slash;
if (c == '\0')
out++;
}
slash = out;
}
if (c == '\0')
break;
//先将内容写入,本保存上一个的内容
pre = c;
c = *walk;
*out = pre;
out++;
walk++;
}
*out = '\0';
return 0;
}
int main(){
char dest[1024];
char path[1024] = "../reage/../reage//aa.c";
buffer_path_simplify(dest, path);
printf("URL=\"%s\" == path=\"%s\"\n", path, dest);
strcpy(path, "/../reage/../../../././reage//aa.c");
buffer_path_simplify(dest, path);
printf("URL=\"%s\" == path=\"%s\"\n", path, dest);
strcpy(path, "/reage/../");
buffer_path_simplify(dest, path);
printf("URL=\"%s\" == path=\"%s\"\n", path, dest);
strcpy(path, "/reage/../reage1");
buffer_path_simplify(dest, path);
printf("URL=\"%s\" == path=\"%s\"\n", path, dest);
strcpy(path, "/reage/./");
buffer_path_simplify(dest, path);
printf("URL=\"%s\" == path=\"%s\"\n", path, dest);
strcpy(path, "/reage//reage");
buffer_path_simplify(dest, path);
printf("URL=\"%s\" == path=\"%s\"\n", path, dest);
}
blog:http://blog.youkuaiyun.com/rentiansheng/article/details/8922368