Browse Source

replace raw C-strings with std::string in converted libfuse files

util/mount.mergerfs.cpp:
- Remove xstrdup/xrealloc wrappers entirely
- Convert type, source, options, command, setuid to std::string
- Replace add_arg() pointer-rewriting with shell_quote() returning std::string
- Replace add_option() with simple std::string += concatenation
- Fix const_cast UB on string literal assignment

lib/helper.cpp:
- Convert add_default_subtype local subtype_opt: malloc+snprintf+free -> std::string construction

lib/mount_generic.h:
- Convert fuse_mount_sys locals source/type: malloc+strcpy+strcat -> std::string
- Remove 4 unnecessary free() calls (RAII cleanup)
- .c_str() at mount() and fuse_mnt_add_mount() boundaries

lib/mount_util.h:
- Rewrite fuse_mnt_resolve_path internals using std::string: rfind/substr
  instead of manual pointer arithmetic, strrchr, strlen chains
fixes
Antonio SJ Musumeci 1 day ago
parent
commit
849a819545
  1. 15
      vendored/libfuse/lib/helper.cpp
  2. 42
      vendored/libfuse/lib/mount_generic.h
  3. 79
      vendored/libfuse/lib/mount_util.h
  4. 179
      vendored/libfuse/util/mount.mergerfs.cpp

15
vendored/libfuse/lib/helper.cpp

@ -13,6 +13,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string>
#include <unistd.h>
#include <string.h>
#include <limits.h>
@ -86,24 +87,14 @@ fuse_helper_opt_proc(void *data,
static int add_default_subtype(const char *progname, struct fuse_args *args)
{
int res;
char *subtype_opt;
const char *basename = strrchr(progname, '/');
if (basename == NULL)
basename = progname;
else if (basename[1] != '\0')
basename++;
size_t optlen = strlen(basename) + 64;
subtype_opt = (char *) malloc(optlen);
if (subtype_opt == NULL) {
fprintf(stderr, "fuse: memory allocation failed\n");
return -1;
}
snprintf(subtype_opt, optlen, "-osubtype=%s", basename);
res = fuse_opt_add_arg(args, subtype_opt);
free(subtype_opt);
return res;
std::string subtype_opt = "-osubtype=" + std::string(basename);
return fuse_opt_add_arg(args, subtype_opt.c_str());
}
int

42
vendored/libfuse/lib/mount_generic.h

@ -16,6 +16,7 @@
#include <unistd.h>
#include <stddef.h>
#include <string.h>
#include <string>
#include <fcntl.h>
#include <errno.h>
#include <poll.h>
@ -407,8 +408,8 @@ fuse_mount_sys(const char *mnt,
{
char tmp[128];
const char *devname = "/dev/fuse";
char *source = NULL;
char *type = NULL;
std::string source;
std::string type;
struct stat stbuf;
int fd;
int res;
@ -478,36 +479,23 @@ fuse_mount_sys(const char *mnt,
if (res == -1)
goto out_close;
source = static_cast<char*>(malloc((mo->fsname ? strlen(mo->fsname) : 0) +
(mo->subtype ? strlen(mo->subtype) : 0) +
strlen(devname) + 32));
type = mo->blkdev ? "fuseblk" : "fuse";
if (mo->subtype)
type += "." + std::string(mo->subtype);
type = static_cast<char*>(malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32));
if (!type || !source) {
fprintf(stderr, "mergerfs: failed to allocate memory\n");
goto out_close;
}
strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
if (mo->subtype) {
strcat(type, ".");
strcat(type, mo->subtype);
}
strcpy(source,
mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname));
source = mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname);
res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
res = mount(source.c_str(), mnt, type.c_str(), mo->flags, mo->kernel_opts);
if (res == -1 && errno == ENODEV && mo->subtype) {
/* Probably missing subtype support */
strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
type = mo->blkdev ? "fuseblk" : "fuse";
if (mo->fsname) {
if (!mo->blkdev)
sprintf(source, "%s#%s", mo->subtype,
mo->fsname);
source = std::string(mo->subtype) + "#" + mo->fsname;
} else {
strcpy(source, type);
source = type;
}
res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
res = mount(source.c_str(), mnt, type.c_str(), mo->flags, mo->kernel_opts);
}
if (res == -1) {
/*
@ -543,7 +531,7 @@ fuse_mount_sys(const char *mnt,
if (!newmnt)
goto out_umount;
res = fuse_mnt_add_mount("fuse", source, newmnt, type,
res = fuse_mnt_add_mount("fuse", source.c_str(), newmnt, type.c_str(),
mnt_opts);
free(newmnt);
if (res == -1)
@ -551,16 +539,12 @@ fuse_mount_sys(const char *mnt,
}
#endif /* IGNORE_MTAB */
#endif /* __NetBSD__ */
free(type);
free(source);
return fd;
out_umount:
umount2(mnt, 2); /* lazy umount */
out_close:
free(type);
free(source);
close(fd);
return res;
}

79
vendored/libfuse/lib/mount_util.h

@ -12,6 +12,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <signal.h>
#include <dirent.h>
#include <errno.h>
@ -249,11 +250,6 @@ int fuse_mnt_remove_mount(const char *progname, const char *mnt)
char *fuse_mnt_resolve_path(const char *progname, const char *orig)
{
char buf[PATH_MAX];
char *copy;
char *dst;
char *end;
char *lastcomp;
const char *toresolv;
if (!orig[0]) {
fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname,
@ -261,57 +257,44 @@ char *fuse_mnt_resolve_path(const char *progname, const char *orig)
return NULL;
}
copy = strdup(orig);
if (copy == NULL) {
fprintf(stderr, "%s: failed to allocate memory\n", progname);
return NULL;
}
std::string copy = orig;
std::string lastcomp;
std::string toresolv;
toresolv = copy;
lastcomp = NULL;
for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --);
if (end[0] != '/') {
char *tmp;
end[1] = '\0';
tmp = strrchr(copy, '/');
if (tmp == NULL) {
lastcomp = copy;
toresolv = ".";
} else {
lastcomp = tmp + 1;
if (tmp == copy)
toresolv = "/";
}
if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) {
lastcomp = NULL;
while (!copy.empty() && copy.back() == '/')
copy.pop_back();
if (!copy.empty() && copy.find('/') != std::string::npos) {
size_t last_slash = copy.find_last_of('/');
lastcomp = copy.substr(last_slash + 1);
toresolv = copy.substr(0, last_slash);
if (lastcomp == "." || lastcomp == "..") {
lastcomp.clear();
toresolv = copy;
}
else if (tmp)
tmp[0] = '\0';
} else if (!copy.empty()) {
lastcomp = copy;
toresolv = ".";
} else {
toresolv = "/";
}
if (realpath(toresolv, buf) == NULL) {
if (realpath(toresolv.c_str(), buf) == NULL) {
fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig,
strerror(errno));
free(copy);
return NULL;
}
if (lastcomp == NULL)
dst = strdup(buf);
else {
unsigned buflen = strlen(buf);
size_t dstlen = buflen + 1 + strlen(lastcomp) + 1;
dst = static_cast<char*>(malloc(dstlen));
if (dst) {
if (buflen && buf[buflen-1] == '/')
snprintf(dst, dstlen, "%s%s", buf, lastcomp);
else
snprintf(dst, dstlen, "%s/%s", buf, lastcomp);
}
}
free(copy);
if (dst == NULL)
fprintf(stderr, "%s: failed to allocate memory\n", progname);
return dst;
std::string dst;
if (lastcomp.empty())
dst = buf;
else if (buf[strlen(buf) - 1] == '/')
dst = std::string(buf) + lastcomp;
else
dst = std::string(buf) + "/" + lastcomp;
return strdup(dst.c_str());
}
int fuse_mnt_check_fuseblk(void)

179
vendored/libfuse/util/mount.mergerfs.cpp

@ -11,111 +11,73 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <string>
static char *progname;
static const char *progname;
static char *xstrdup(const char *s)
static std::string shell_quote(const std::string &s)
{
char *t = strdup(s);
if (!t) {
fprintf(stderr, "%s: failed to allocate memory\n", progname);
exit(1);
}
return t;
}
std::string r = "'";
static void *xrealloc(void *oldptr, size_t size)
{
void *ptr = realloc(oldptr, size);
if (!ptr) {
fprintf(stderr, "%s: failed to allocate memory\n", progname);
exit(1);
for (char c : s) {
if (c == '\'')
r += "'\\''";
else
r += c;
}
return ptr;
}
r += "'";
static void add_arg(char **cmdp, const char *opt)
{
size_t optlen = strlen(opt);
size_t cmdlen = *cmdp ? strlen(*cmdp) : 0;
char *cmd = static_cast<char*>(xrealloc(*cmdp, cmdlen + optlen * 4 + 4));
char *s;
s = cmd + cmdlen;
if (*cmdp)
*s++ = ' ';
*s++ = '\'';
for (; *opt; opt++) {
if (*opt == '\'') {
*s++ = '\'';
*s++ = '\\';
*s++ = '\'';
*s++ = '\'';
} else
*s++ = *opt;
}
*s++ = '\'';
*s = '\0';
*cmdp = cmd;
return r;
}
static char *add_option(const char *opt, char *options)
static std::string add_option(const std::string &opt,
const std::string &options)
{
int oldlen = options ? strlen(options) : 0;
options = static_cast<char*>(xrealloc(options, oldlen + 1 + strlen(opt) + 1));
if (!oldlen)
strcpy(options, opt);
else {
strcat(options, ",");
strcat(options, opt);
}
return options;
if (options.empty())
return opt;
return options + "," + opt;
}
int main(int argc, char *argv[])
{
char *type = NULL;
char *source;
const char *mountpoint;
char *basename;
char *options = NULL;
char *command = NULL;
char *setuid = NULL;
int i;
std::string type;
std::string source;
std::string mountpoint;
std::string basename;
std::string options;
std::string command;
std::string setuid;
int dev = 1;
int suid = 1;
progname = argv[0];
basename = strrchr(argv[0], '/');
if (basename)
basename++;
else
basename = argv[0];
{
const char *slash = strrchr(argv[0], '/');
basename = slash ? (slash + 1) : argv[0];
}
type = const_cast<char*>("mergerfs");
if (strncmp(basename, "mount.fuse.", 11) == 0)
type = basename + 11;
if (strncmp(basename, "mount.fuseblk.", 14) == 0)
type = basename + 14;
type = "mergerfs";
if (strncmp(basename.c_str(), "mount.fuse.", 11) == 0)
type = basename.substr(11);
if (strncmp(basename.c_str(), "mount.fuseblk.", 14) == 0)
type = basename.substr(14);
if (type && !type[0])
type = NULL;
if (type.empty())
type = "";
if (argc < 3) {
fprintf(stderr,
"usage: %s %s destination [-t type] [-o opt[,opts...]]\n",
progname, type ? "source" : "type#[source]");
progname, type.empty() ? "type#[source]" : "source");
exit(1);
}
source = argv[1];
if (!source[0])
source = NULL;
mountpoint = argv[2];
for (i = 3; i < argc; i++) {
for (int i = 3; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0) {
continue;
} else if (strcmp(argv[i], "-t") == 0) {
@ -128,25 +90,25 @@ int main(int argc, char *argv[])
exit(1);
}
type = argv[i];
if (strncmp(type, "fuse.", 5) == 0)
type += 5;
else if (strncmp(type, "fuseblk.", 8) == 0)
type += 8;
if (strncmp(type.c_str(), "fuse.", 5) == 0)
type = type.substr(5);
else if (strncmp(type.c_str(), "fuseblk.", 8) == 0)
type = type.substr(8);
if (!type[0]) {
if (type.empty()) {
fprintf(stderr,
"%s: empty type given as argument to option '-t'\n",
progname);
exit(1);
}
} else if (strcmp(argv[i], "-o") == 0) {
} else if (strcmp(argv[i], "-o") == 0) {
char *opts;
char *opt;
i++;
if (i == argc)
break;
opts = xstrdup(argv[i]);
opts = strdup(argv[i]);
opt = strtok(opts, ",");
while (opt)
{
@ -165,7 +127,7 @@ int main(int argc, char *argv[])
NULL
};
if (strncmp(opt, "setuid=", 7) == 0) {
setuid = xstrdup(opt + 7);
setuid = opt + 7;
ignore = 1;
}
for (j = 0; ignore_opts[j]; j++)
@ -182,6 +144,7 @@ int main(int argc, char *argv[])
}
opt = strtok(NULL, ",");
}
free(opts);
}
}
@ -190,13 +153,17 @@ int main(int argc, char *argv[])
if (suid)
options = add_option("suid", options);
if (!type) {
if (source) {
type = xstrdup(source);
source = strchr(type, '#');
if (source)
*source++ = '\0';
if (!type[0]) {
if (type.empty()) {
if (!source.empty()) {
size_t hash_pos = source.find('#');
if (hash_pos != std::string::npos) {
type = source.substr(0, hash_pos);
source = source.substr(hash_pos + 1);
} else {
type = source;
source.clear();
}
if (type.empty()) {
fprintf(stderr, "%s: empty filesystem type\n",
progname);
exit(1);
@ -207,29 +174,27 @@ int main(int argc, char *argv[])
}
}
add_arg(&command, type);
if (source)
add_arg(&command, source);
add_arg(&command, mountpoint);
if (options) {
add_arg(&command, "-o");
add_arg(&command, options);
command += shell_quote(type);
if (!source.empty())
command += " " + shell_quote(source);
command += " " + shell_quote(mountpoint);
if (!options.empty()) {
command += " " + shell_quote("-o");
command += " " + shell_quote(options);
}
if (setuid && setuid[0]) {
char *sucommand = command;
command = NULL;
add_arg(&command, "su");
add_arg(&command, "-");
add_arg(&command, setuid);
add_arg(&command, "-c");
add_arg(&command, sucommand);
if (!setuid.empty()) {
std::string sucommand = command;
command = "su";
command += " -";
command += " " + shell_quote(setuid);
command += " -c";
command += " " + shell_quote(sucommand);
} else if (!getenv("HOME")) {
/* Hack to make filesystems work in the boot environment */
setenv("HOME", "/root", 0);
}
execl("/bin/sh", "/bin/sh", "-c", command, NULL);
execl("/bin/sh", "/bin/sh", "-c", command.c_str(), NULL);
fprintf(stderr, "%s: failed to execute /bin/sh: %s\n", progname,
strerror(errno));
return 1;

Loading…
Cancel
Save