On Sun, Feb 12, 2023 at 09:16:58PM +0000, Job Snijders wrote: > I noticed there is an issue in openrsync when a port is specified in the > rsync:// URL, the port number ends up becoming part of the path: > > $ openrsync -r rsync://rsync.roa.tohunet.com:3873/repo/ /tmp/r > rsync: [sender] change_dir "/3873/repo" (in repo) failed: No such file or > directory (2) > > The below changeset seems to improve the situation, but might not be the > best way to fix it. I found fargs_parse() a bit hard to understand.
No kidding... > OK? Suggestions? > > Kind regards, > > Job > > Index: main.c > =================================================================== > RCS file: /cvs/src/usr.bin/rsync/main.c,v > retrieving revision 1.65 > diff -u -p -r1.65 main.c > --- main.c 2 Aug 2022 20:01:12 -0000 1.65 > +++ main.c 12 Feb 2023 21:06:00 -0000 > @@ -233,8 +233,12 @@ fargs_parse(size_t argc, char *argv[], s > strncasecmp(cp, "rsync://", 8) == 0) { > /* rsync://path */ > cp += 8; > - if ((ccp = strchr(cp, ':'))) /* skip :port */ > + /* skip :port */ > + if ((ccp = strchr(cp, ':')) != NULL) { > *ccp = '\0'; > + while (cp[len] != '/' && len < j) > + len++; > + } There are various issues here. First, you don't know that cp[len] is in any way related to the location of ':' in the string since the strncmp() only happens later. This is equivalent to your while loop but starting at what we know to be after the colon: len += strcspn(ccp + 1, "/") + 1; This brings me to the next problem: we must not modify len, as it is the length of f->host. If there are multiple sources, len my grow and eventually cp[len] could access out of bounds. While it is not super clean, the easiest fix for this would be to do /* rsync://path[:host] */ size_t save_len = len; after the strncasecmp() above, then after the memmove() at the end of the scope reset the length to what it originally was: len = save_len; A bit cleaner would be to replace uses of len with /* rsync://path[:host] */ size_t module_offset = len; ... module_offset += strcspn(ccp + 1, "/") + 1; then replace all uses of len in this scope *after* the strncmp below with module_offset. > if (strncmp(cp, f->host, len) || > (cp[len] != '/' && cp[len] != '\0')) > errx(ERR_SYNTAX, "different remote host: %s", >