MCPcopy Index your code
hub / github.com/RsyncProject/rsync / sanitize_path

Function sanitize_path

util1.c:1056–1129  ·  view source on GitHub ↗

Make path appear as if a chroot had occurred. This handles a leading * "/" (either removing it or expanding it) and any leading or embedded * ".." components that attempt to escape past the module's top dir. * * If dest is NULL, a buffer is allocated to hold the result. It is legal * to call with the dest and the path (p) pointing to the same buffer, but * rootdir will be ignored to avoid

Source from the content-addressed store, hash-verified

1054 * string up to "depth" deep). If the resulting name would be empty,
1055 * change it into a ".". */
1056char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth, int flags)
1057{
1058 char *start, *sanp;
1059 int rlen = 0, drop_dot_dirs = !relative_paths || !(flags & SP_KEEP_DOT_DIRS);
1060
1061 if (dest != p) {
1062 int plen = strlen(p); /* the path len INCLUDING any separating slash */
1063 if (*p == '/') {
1064 if (!rootdir)
1065 rootdir = module_dir;
1066 rlen = strlen(rootdir);
1067 depth = 0;
1068 p++;
1069 }
1070 if (!dest)
1071 dest = new_array(char, MAX(rlen + plen + 1, 2));
1072 else if (rlen + plen + 1 >= MAXPATHLEN)
1073 return NULL;
1074 if (rlen) { /* only true if p previously started with a slash */
1075 memcpy(dest, rootdir, rlen);
1076 if (rlen > 1) /* a rootdir of len 1 is "/", so this avoids a 2nd slash */
1077 dest[rlen++] = '/';
1078 }
1079 }
1080
1081 if (drop_dot_dirs) {
1082 while (*p == '.' && p[1] == '/')
1083 p += 2;
1084 }
1085
1086 start = sanp = dest + rlen;
1087 /* This loop iterates once per filename component in p, pointing at
1088 * the start of the name (past any prior slash) for each iteration. */
1089 while (*p) {
1090 /* discard leading or extra slashes */
1091 if (*p == '/') {
1092 p++;
1093 continue;
1094 }
1095 if (drop_dot_dirs) {
1096 if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
1097 /* skip "." component */
1098 p++;
1099 continue;
1100 }
1101 }
1102 if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
1103 /* ".." component followed by slash or end */
1104 if (depth <= 0 || sanp != start) {
1105 p += 2;
1106 if (sanp != start) {
1107 /* back up sanp one level */
1108 --sanp; /* now pointing at slash */
1109 while (sanp > start && sanp[-1] != '/')
1110 sanp--;
1111 }
1112 continue;
1113 }

Callers 8

parse_argumentsFunction · 0.85
parse_merge_nameFunction · 0.85
glob_expandFunction · 0.85
read_ndx_and_attrsFunction · 0.85
recv_file_entryFunction · 0.85
make_fileFunction · 0.85
send_file_listFunction · 0.85
do_server_recvFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected