boolean (@NotNull StringBuilder result, int dots, int start, @Nullable SymlinkResolver symlinkResolver) { if (dots == 2) { int pos = -1; if (!StringUtilRt.endsWith(result, "/../") && !"../".contentEquals(result)) { pos = StringUtilRt.lastIndexOf(result, '/', start, result.length() - 1); if (pos >= 0) { ++pos; // separator found, trim to next char } else if (start > 0) { pos = start; // path is absolute, trim to root ('/..' -> '/') } else if (result.length() > 0) { pos = 0; // path is relative, trim to default ('a/..' -> '') } } if (pos >= 0) { if (symlinkResolver != null && symlinkResolver.isSymlink(result)) { return false; } result.delete(pos, result.length()); } else { result.append("../"); // impossible to traverse, keep as-is } } else if (dots != 1) { for (int i = 0; i < dots; i++) { result.append('.'); } result.append('/'); } return true; }