本次为了方便展示和调试,并没有将代买写入到真实的运行环境,而是单独写了一个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/http://www.cnblogs.com/../././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.csdn.net/rentiansheng/article/details/8922368