Commit Diff


commit - 62c0f697ddc7396384280f2f8bac7a092700f1ba
commit + c6432d394ee01ce54bac5def39e490a9de261cc3
blob - 9a44d9597949d1e4c46f5778bb4d34da0f552753
blob + 1889d871eb431f8caf500fd60d8775627234eb4c
--- iri.c
+++ iri.c
@@ -643,65 +643,35 @@ iri_parse(const char *base, const char *str, struct ir
 int
 iri_unparse(const struct iri *i, char *buf, size_t buflen)
 {
-	if (buflen == 0)
-		goto err;
-
-	/* TODO: should %enc octets if needed */
-
-	buf[0] = '\0';
-
-	if (i->iri_flags & IH_SCHEME) {
-		if (strlcat(buf, i->iri_scheme, buflen) >= buflen ||
-		    strlcat(buf, ":", buflen) >= buflen)
-			goto err;
-	}
+	int	 need_ss, have_path, need_s;
+	int	 r;
 
-	if (i->iri_flags & IH_AUTHORITY) {
-		if (strlcat(buf, "//", buflen) >= buflen)
-			goto err;
-	}
-
-	if (i->iri_flags & IH_UINFO) {
-		if (strlcat(buf, i->iri_uinfo, buflen) >= buflen ||
-		    strlcat(buf, "@", buflen) >= buflen)
-			goto err;
-	}
-	if (i->iri_flags & IH_HOST) {
-		if (strlcat(buf, i->iri_host, buflen) >= buflen)
-			goto err;
-	}
-	if (i->iri_flags & IH_PORT) {
-		if (strlcat(buf, ":", buflen) >= buflen ||
-		    strlcat(buf, i->iri_portstr, buflen) >= buflen)
-			goto err;
-	}
+	need_ss = (i->iri_flags & IH_AUTHORITY);
+	have_path = i->iri_flags & IH_PATH;
+	need_s = have_path && (i->iri_flags & IH_AUTHORITY) &&
+	    i->iri_path[0] != '/';
 
-	if (i->iri_flags & IH_PATH) {
-		if (i->iri_flags & IH_AUTHORITY &&
-		    i->iri_path[0] != '/' &&
-		    strlcat(buf, "/", buflen) >= buflen)
-			goto err;
-		if (strlcat(buf, i->iri_path, buflen) >= buflen)
-			goto err;
+	r = snprintf(buf, buflen, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+	    (i->iri_flags & IH_SCHEME) ? i->iri_scheme : "",
+	    (i->iri_flags & IH_SCHEME) ? ":" : "",
+	    need_ss ? "//" : "",
+	    (i->iri_flags & IH_UINFO) ? i->iri_uinfo : "",
+	    (i->iri_flags & IH_UINFO) ? "@" : "",
+	    (i->iri_flags & IH_HOST) ? i->iri_host : "",
+	    (i->iri_flags & IH_PORT) ? ":" : "",
+	    (i->iri_flags & IH_PORT) ? i->iri_portstr : "",
+	    need_s ? "/" : "",
+	    have_path ? i->iri_path : "",
+	    (i->iri_flags & IH_QUERY) ? "?" : "",
+	    (i->iri_flags & IH_QUERY) ? i->iri_query : "",
+	    (i->iri_flags & IH_FRAGMENT) ? "#" : "",
+	    (i->iri_flags & IH_FRAGMENT) ? i->iri_fragment : "");
+	if (r < 0 || (size_t)r >= buflen) {
+		errno = ENOBUFS;
+		return (-1);
 	}
 
-	if (i->iri_flags & IH_QUERY) {
-		if (strlcat(buf, "?", buflen) >= buflen ||
-		    strlcat(buf, i->iri_query, buflen) >= buflen)
-			goto err;
-	}
-
-	if (i->iri_flags & IH_FRAGMENT) {
-		if (strlcat(buf, "#", buflen) >= buflen ||
-		    strlcat(buf, i->iri_fragment, buflen) >= buflen)
-			goto err;
-	}
-
 	return (0);
-
- err:
-	errno = ENOBUFS;
-	return (-1);
 }
 
 int