commit 69942b73fa48871099028f5c6370c4493d3691cb from: Omar Polo date: Mon Dec 26 17:51:28 2022 UTC iri: make mergepath take a buffer and strings, not the iri pointers commit - d2d73a094eb58f7ecf091d401f4d33ca905e17cd commit + 69942b73fa48871099028f5c6370c4493d3691cb blob - 3ef5adffb4966a3003b993abc2656429566e5baf blob + 2adbaf8ce87337515f25d8beb7afc72026b4dea9 --- iri.c +++ iri.c @@ -538,32 +538,33 @@ remove_dot_segments(char *buf, ptrdiff_t bufsize) } static inline int -mergepath(struct iri *i, struct iri *base, struct iri *r) +mergepath(char *buf, size_t bufsize, int abs, const char *base, const char *r) { - const char *bpath, *rpath, *s; + const char *s; - bpath = (base->iri_flags & IH_PATH) ? base->iri_path : "/"; - rpath = (r->iri_flags & IH_PATH) ? r->iri_path : "/"; + if (base == NULL || *base == '\0') + base = "/"; + if (r == NULL || *r == '\0') + r = "/"; - i->iri_flags |= IH_PATH; - i->iri_path[0] = '\0'; + if (bufsize == 0) + return (-1); + buf[0] = '\0'; - if ((base->iri_flags & IH_AUTHORITY) && - (*bpath == '\0' || !strcmp(bpath, "/"))) { - if (*rpath == '/') - rpath++; - strlcpy(i->iri_path, "/", sizeof(i->iri_path)); - strlcat(i->iri_path, rpath, sizeof(i->iri_path)); + if (abs && (*base == '\0' || !strcmp(base, "/"))) { + if (*r == '/') + r++; + strlcpy(buf, "/", bufsize); + strlcat(buf, r, bufsize); return (0); } - if ((s = strrchr(bpath, '/')) != NULL) { - cpstr(bpath, s + 1, i->iri_path, sizeof(i->iri_path)); - if (*rpath == '/') - rpath++; + if ((s = strrchr(base, '/')) != NULL) { + cpstr(base, s + 1, buf, bufsize); + if (*r == '/') + r++; } - if (strlcat(i->iri_path, rpath, sizeof(i->iri_path)) >= - sizeof(i->iri_path)) { + if (strlcat(buf, r, bufsize) >= bufsize) { errno = ENAMETOOLONG; return (-1); } @@ -627,8 +628,11 @@ iri_parse(const char *base, const char *str, struct ir ibase.iri_path[0] = '\0'; if (!(iparsed.iri_flags & IH_PATH)) iparsed.iri_path[0] = '\0'; - if (mergepath(iri, &ibase, &iparsed) == -1) + if (mergepath(iri->iri_path, sizeof(iri->iri_path), + ibase.iri_flags & IH_AUTHORITY, ibase.iri_path, + iparsed.iri_path) == -1) return (-1); + iri->iri_flags |= IH_PATH; } if (remove_dot_segments(iri->iri_path, sizeof(iri->iri_path)) == -1) return (-1);