NetBSD Problem Report #60346

From mlelstv@arnold.1st.de  Sun Jun 21 07:35:48 2026
Return-Path: <mlelstv@arnold.1st.de>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits)
	 client-signature RSA-PSS (2048 bits))
	(Client CN "mail.netbsd.org", Issuer "R13" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 4887E1A923A
	for <gnats-bugs@gnats.NetBSD.org>; Sun, 21 Jun 2026 07:35:48 +0000 (UTC)
Message-Id: <20260621073326.45292BC164@arnold.1st.de>
Date: Sun, 21 Jun 2026 09:33:26 +0200 (CEST)
From: mlelstv@serpens.de
Reply-To: mlelstv@serpens.de
To: gnats-bugs@NetBSD.org
Subject: ftp failure when handling redirect through HTTP proxy
X-Send-Pr-Version: 3.95
X-From4GNATS: "mlelstv@serpens.de via gnats" <gnats-admin@NetBSD.org>

>Number:         60346
>Category:       bin
>Synopsis:       ftp failure when handling redirect through HTTP proxy
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jun 21 07:40:00 +0000 2026
>Last-Modified:  Sat Jul 18 23:00:01 +0000 2026
>Originator:     Michael van Elst
>Release:        NetBSD 11.99.6
>Organization:

>Environment:


System: NetBSD arnold 11.99.6 NetBSD 11.99.6 (EGGHED64) #0: Sat Jun 6 12:50:49 UTC 2026 mlelstv@slowpoke:/home/netbsd-current/obj.evbarm64-el/scratch/netbsd-current/src/sys/arch/evbarm/compile/EGGHED64 evbarm
Architecture: aarch64
Machine: evbarm
>Description:

Using ftp(1) to fetch e.g.:

https://nycdn.netbsd.org/pub/NetBSD-daily/netbsd-11/latest/LAST_MINUTE

results in an error when the query is sent through a http proxy. E.g:

% ftp https://nycdn.netbsd.org/pub/NetBSD-daily/netbsd-11/latest/LAST_MINUTE
Trying [2a01:170:1141:404:9e5c:8eff:fe77:744e]:3128 ...
Requesting https://nycdn.netbsd.org/pub/NetBSD-daily/netbsd-11/latest/LAST_MINUTE
  (via proxy.local:3128)
Redirected to /pub/NetBSD-daily/netbsd-11/20260616154807Z/LAST_MINUTE
Trying [2a01:170:1141:404:9e5c:8eff:fe77:744e]:3128 ...
Requesting /pub/NetBSD-daily/netbsd-11/20260616154807Z/LAST_MINUTE
  (via proxy.local:3128)
ftp: Error retrieving file `400 Bad Request'

The reason ist that the 'latest' path is redirected to a relative
URL. This works without proxy as the web server understands the
relative URL. But a proxy must be queried with an absolute URL.

>How-To-Repeat:

Try to fetch from NetBSD-daily using the 'latest' path and using
a HTTP proxy.

>Fix:

Maybe this:

Index: usr.bin/ftp/fetch.c
===================================================================
RCS file: /cvsroot/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.246
diff -p -u -r1.246 fetch.c
--- usr.bin/ftp/fetch.c	8 Feb 2026 09:00:54 -0000	1.246
+++ usr.bin/ftp/fetch.c	21 Jun 2026 07:32:25 -0000
@@ -115,6 +115,7 @@ static int	parse_url(const char *, const
 static void	url_decode(char *);
 static void	freeauthinfo(struct authinfo *);
 static void	freeurlinfo(struct urlinfo *);
+static char	*make_absurl(char *, const char *);

 static int	redirect_loop;

@@ -1115,6 +1116,41 @@ do_auth(int hcode, const char *url, cons
 }
 #endif

+static char *
+make_absurl(char *url, const char *prevurl)
+{
+	const char *proto, *hostport, *path;
+	char *buf;
+	size_t len;
+
+#ifdef WITH_SSL
+	if (STRNEQUAL(prevurl, HTTPS_URL))
+		proto = HTTPS_URL;
+	else
+#endif
+	if (STRNEQUAL(prevurl, HTTP_URL))
+		proto = HTTP_URL;
+	else
+		return url;
+
+	len = strlen(proto);
+	hostport = prevurl + len;
+	path = strchr(hostport, '/');
+	if (path != NULL)
+		len += path - hostport;
+	else
+		len += strlen(hostport);
+
+	buf = ftp_malloc(len + strlen(url) + 1);
+
+	strncpy(buf, prevurl, len);
+	strcat(buf, url);
+
+	FREEPTR(url);
+
+	return buf;
+}
+
 static int
 negotiate_connection(FETCH *fin, const char *url, const char *penv,
     struct posinfo *pi, time_t *mtime, struct authinfo *wauth,
@@ -1246,6 +1282,8 @@ negotiate_connection(FETCH *fin, const c
 			if (verbose)
 				fprintf(ttyout, "Redirected to %s\n",
 				    location);
+			if (location[0] == '/')
+				location = make_absurl(location, url);
 			*rval = go_fetch(location, ui);
 		}
 		goto cleanup_fetch_url;

>Audit-Trail:
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/60346: ftp failure when handling redirect through HTTP proxy
Date: Thu, 25 Jun 2026 21:03:13 -0000 (UTC)

 gnats-admin@NetBSD.org ("mlelstv@serpens.de via gnats") writes:

 >>Fix:
 >Maybe this:

 Here is a more complete handling of relative URLs.

 Index: usr.bin/ftp/Makefile
 ===================================================================
 RCS file: /cvsroot/src/usr.bin/ftp/Makefile,v
 retrieving revision 1.45
 diff -p -u -r1.45 Makefile
 --- usr.bin/ftp/Makefile	8 Feb 2026 09:00:54 -0000	1.45
 +++ usr.bin/ftp/Makefile	25 Jun 2026 20:55:25 -0000
 @@ -7,7 +7,7 @@ USE_FORT?= yes	# network client

  PROG=	ftp
  SRCS=	cmds.c cmdtab.c complete.c domacro.c fetch.c ftp.c main.c \
 -	progressbar.c ruserpass.c util.c
 +	progressbar.c ruserpass.c uri.c util.c
  SRCS+=	ssl.c

  # Uncomment the following to provide defaults for gate-ftp operation
 Index: usr.bin/ftp/fetch.c
 ===================================================================
 RCS file: /cvsroot/src/usr.bin/ftp/fetch.c,v
 retrieving revision 1.246
 diff -p -u -r1.246 fetch.c
 --- usr.bin/ftp/fetch.c	8 Feb 2026 09:00:54 -0000	1.246
 +++ usr.bin/ftp/fetch.c	25 Jun 2026 20:55:25 -0000
 @@ -68,6 +68,7 @@ __RCSID("$NetBSD: fetch.c,v 1.246 2026/0

  #include "ssl.h"
  #include "ftp_var.h"
 +#include "uri.h"
  #include "version.h"

  typedef enum {
 @@ -1246,6 +1247,7 @@ negotiate_connection(FETCH *fin, const c
  			if (verbose)
  				fprintf(ttyout, "Redirected to %s\n",
  				    location);
 +			location = make_absurl(location, url);
  			*rval = go_fetch(location, ui);
  		}
  		goto cleanup_fetch_url;
 Index: usr.bin/ftp/uri.c
 ===================================================================
 RCS file: usr.bin/ftp/uri.c
 diff -N usr.bin/ftp/uri.c
 --- /dev/null	1 Jan 1970 00:00:00 -0000
 +++ usr.bin/ftp/uri.c	25 Jun 2026 20:55:25 -0000
 @@ -0,0 +1,304 @@
 +/*	$NetBSD: $	*/
 +
 +/*-
 + * Copyright (c) 2026 The NetBSD Foundation, Inc.
 + * All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 + * POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#include <stdlib.h>
 +#include <string.h>
 +
 +#include "ssl.h"
 +#include "ftp_var.h"
 +#include "uri.h"
 +
 +typedef struct {
 +	char *buf;
 +	size_t scheme;
 +	size_t authority;
 +	size_t path;
 +	size_t query;
 +	size_t fragment;
 +} uriparts_t;
 +
 +#define SCHEME(p) ((p)->buf)
 +#define AUTHORITY(p) (SCHEME(p) + (p)->scheme)
 +#define PATH(p) (AUTHORITY(p) + (p)->authority)
 +#define QUERY(p) (PATH(p) + (p)->path)
 +#define FRAGMENT(p) (QUERY(p) + (p)->query)
 +
 +static void
 +split_uri(char *uri, uriparts_t *parts)
 +{
 +	char *colon, *slash, *query, *sharp;
 +
 +	parts->buf = uri;
 +	parts->scheme = 0;
 +	parts->authority = 0;
 +	parts->path = 0;
 +	parts->query = 0;
 +	parts->fragment = 0;
 +
 +	colon = strchr(uri, ':');
 +	slash = strchr(uri, '/');
 +	if (colon && (slash == NULL || (colon - uri) < (slash - uri))) {
 +		parts->scheme = colon + 1 - uri;
 +		uri = colon + 1;
 +	}       
 +
 +	if (uri[0] == '/' && uri[1] == '/') {
 +		slash = strchr(uri + 2, '/');
 +		if (slash == NULL) {
 +			parts->authority = strlen(uri); 
 +			return;
 +		}
 +		parts->authority = slash - uri;
 +		uri = slash;
 +	}       
 +
 +	query = strchr(uri, '?');
 +	sharp = strchr(uri, '#');
 +	if (query && (sharp == NULL || (query - uri) < (sharp - uri))) {
 +		parts->path = query - uri;
 +		uri = query;
 +		if (sharp != NULL) {
 +			parts->query = sharp - query;
 +			parts->fragment = strlen(sharp);
 +			return;
 +		}
 +		parts->query = strlen(query);
 +		return;
 +	}
 +
 +	if (sharp != NULL) {
 +		parts->path = sharp - uri;
 +		parts->fragment = strlen(sharp);
 +		return;
 +	}
 +
 +	parts->path = strlen(uri);
 +}
 +
 +static char *
 +build_uri(uriparts_t *s, uriparts_t *a, uriparts_t *p,
 +    uriparts_t *q, uriparts_t *f)
 +{
 +	size_t len;
 +	char *buf, *out;
 +
 +	len = s->scheme + a->authority + p->path + q->query + f->fragment;
 +	buf = ftp_malloc(len + 1);
 +
 +	out = buf;
 +	memcpy(out, SCHEME(s), s->scheme);
 +	out += s->scheme;
 +	memcpy(out, AUTHORITY(a), a->authority);
 +	out += a->authority;
 +	memcpy(out, PATH(p), p->path);
 +	out += p->path;
 +	memcpy(out, QUERY(q), q->query);
 +	out += q->query;
 +	memcpy(out, FRAGMENT(f), f->fragment);
 +	out += f->fragment;
 +
 +	return buf;
 +}
 +
 +static char *
 +remove_dot_segments(const char *path, size_t len)
 +{
 +	char *p;
 +	char *buf, *out, *seg;
 +	size_t n;
 +
 +	p = ftp_malloc(len + 1);
 +	strcpy(p, path);
 +
 +	buf = ftp_malloc(len + 1);
 +	out = buf;
 +	*out = '\0';
 +
 +	while (len > 0) {
 +		/* A */
 +		if (p[0] == '.') {
 +			if (len > 1 && p[1] == '/') {
 +				p += 2;
 +				len -= 2;
 +				continue;
 +			} else if (len > 2 && p[1] == '.' && p[2] == '/') {
 +				p += 3;
 +				len -= 3;
 +				continue;
 +			}
 +		}
 +
 +		/* B */
 +		if (p[0] == '/') {
 +			if (len > 2 && p[1] == '.' && p[2] == '/') {
 +				p += 2;
 +				len -= 2;
 +				continue;
 +			} else if (len > 1 && p[1] == '.') {
 +				p += 1;
 +				len -= 1;
 +				p[0] = '/';
 +				continue;
 +			}
 +		}
 +
 +		/* C */
 +		if (len > 2 && p[0] == '/' && p[1] == '.' && p[2] == '.') {
 +			if (len > 3 && p[3] == '/') {
 +				p += 3;
 +				len -= 3;
 +			} else {
 +				p += 2;
 +				len -= 2;
 +				p[0] = '/';
 +			}
 +			seg = strrchr(buf, '/');
 +			if (seg != NULL)
 +				*seg = '\0';
 +			continue;
 +		}
 +
 +		/* D */
 +		if (p[0] == '.') {
 +			if (len == 1) {
 +				p += 1;
 +				len -= 1;
 +				continue;
 +			} else if (len == 2 && p[1] == '.') {
 +				p += 2;
 +				len -= 2;
 +				continue;
 +			}
 +		}
 +
 +		/* E */
 +		if (p[0] == '/') {
 +			seg = strchr(p+1, '/');
 +		} else {
 +			seg = strchr(p, '/');
 +		}
 +		if (seg != NULL)
 +			n = seg - p;
 +		else
 +			n = len;
 +
 +		memcpy(out, p, n);
 +		out += n;
 +		*out = '\0';
 +		p += n;
 +		len -= n;
 +	};
 +
 +	FREEPTR(p);
 +
 +	return buf;
 +}
 +
 +static char *
 +merge_paths(uriparts_t *base, uriparts_t *ref)
 +{
 +	char *buf;
 +	const char *path, *last;
 +	size_t len;
 +
 +	if (base->authority && base->path == 0) {
 +		len = 1 + ref->path;
 +		buf = ftp_malloc(len + 1);
 +		buf[0] = '/';
 +		memcpy(buf + 1, PATH(ref), ref->path);
 +	} else {
 +		path = PATH(base);
 +		last = strrchr(path, '/');
 +		if (last == NULL || (size_t)(last - path) > base->path)
 +			len = 0;
 +		else
 +			len = (size_t)(last - path) + 1;
 +		buf = ftp_malloc(len + ref->path + 1);
 +		memcpy(buf, path, len);
 +		memcpy(buf + len, PATH(ref), ref->path);
 +		len += ref->path;
 +	}
 +	buf[len] = '\0';
 +
 +	return buf;
 +}
 +
 +char *
 +make_absurl(char *refurl, char *baseurl)
 +{
 +	uriparts_t base;
 +	uriparts_t ref;
 +	uriparts_t tmp;
 +	char *buf, *tmp2;
 +	
 +	split_uri(baseurl, &base);
 +	split_uri(refurl, &ref);
 +
 +	tmp.scheme = tmp.authority = tmp.path = tmp.query = tmp.fragment = 0;
 +
 +	if (ref.scheme) {
 +		tmp.buf = remove_dot_segments(PATH(&ref), ref.path);
 +		tmp.path = strlen(tmp.buf);
 +		buf = build_uri(&ref, &ref, &tmp, &ref, &ref);
 +		FREEPTR(tmp.buf);
 +	} else {
 +		if (ref.authority) {
 +			tmp.buf = remove_dot_segments(PATH(&ref), ref.path);
 +			tmp.path = strlen(tmp.buf);
 +			buf = build_uri(&base, &ref, &tmp, &ref, &ref);
 +			FREEPTR(tmp.buf);
 +		} else {
 +			if (ref.path == 0) {
 +				if (ref.query) {
 +					buf = build_uri(&base, &base, &base, &ref, &ref);
 +				} else {
 +					buf = build_uri(&base, &base, &base, &base, &ref);
 +				}
 +			} else {
 +				if (PATH(&ref)[0] == '/') {
 +					tmp.buf = remove_dot_segments(PATH(&ref), ref.path);
 +					tmp.path = strlen(tmp.buf);
 +					buf = build_uri(&base, &base, &tmp, &ref, &ref);
 +					FREEPTR(tmp.buf);
 +				} else {
 +					tmp2 = merge_paths(&base, &ref);
 +					tmp.buf = remove_dot_segments(tmp2, strlen(tmp2));
 +					tmp.path = strlen(tmp.buf);
 +					FREEPTR(tmp2);
 +
 +					buf = build_uri(&base, &base, &tmp, &ref, &ref);
 +					FREEPTR(tmp.buf);
 +				}
 +			}
 +		}
 +	}
 +
 +	FREEPTR(refurl);
 +
 +	return buf;
 +}
 Index: usr.bin/ftp/uri.h
 ===================================================================
 RCS file: usr.bin/ftp/uri.h
 diff -N usr.bin/ftp/uri.h
 --- /dev/null	1 Jan 1970 00:00:00 -0000
 +++ usr.bin/ftp/uri.h	25 Jun 2026 20:55:25 -0000
 @@ -0,0 +1,29 @@
 +/*	$NetBSD: $	*/
 +
 +/*-
 + * Copyright (c) 2026 The NetBSD Foundation, Inc.
 + * All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 + * POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +char *make_absurl(char *, char *);

From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/60346: ftp failure when handling redirect through HTTP proxy
Date: Sat, 27 Jun 2026 05:10:30 -0000 (UTC)

 gnats-admin@NetBSD.org ("Michael van Elst via gnats") writes:

 > Here is a more complete handling of relative URLs.

 And with some bug fixes...

 Index: usr.bin/ftp/Makefile
 ===================================================================
 RCS file: /cvsroot/src/usr.bin/ftp/Makefile,v
 retrieving revision 1.45
 diff -p -u -r1.45 Makefile
 --- usr.bin/ftp/Makefile	8 Feb 2026 09:00:54 -0000	1.45
 +++ usr.bin/ftp/Makefile	27 Jun 2026 05:01:06 -0000
 @@ -7,7 +7,7 @@ USE_FORT?= yes	# network client

  PROG=	ftp
  SRCS=	cmds.c cmdtab.c complete.c domacro.c fetch.c ftp.c main.c \
 -	progressbar.c ruserpass.c util.c
 +	progressbar.c ruserpass.c uri.c util.c
  SRCS+=	ssl.c

  # Uncomment the following to provide defaults for gate-ftp operation
 Index: usr.bin/ftp/fetch.c
 ===================================================================
 RCS file: /cvsroot/src/usr.bin/ftp/fetch.c,v
 retrieving revision 1.246
 diff -p -u -r1.246 fetch.c
 --- usr.bin/ftp/fetch.c	8 Feb 2026 09:00:54 -0000	1.246
 +++ usr.bin/ftp/fetch.c	27 Jun 2026 05:01:07 -0000
 @@ -68,6 +68,7 @@ __RCSID("$NetBSD: fetch.c,v 1.246 2026/0

  #include "ssl.h"
  #include "ftp_var.h"
 +#include "uri.h"
  #include "version.h"

  typedef enum {
 @@ -1246,6 +1247,7 @@ negotiate_connection(FETCH *fin, const c
  			if (verbose)
  				fprintf(ttyout, "Redirected to %s\n",
  				    location);
 +			location = make_absurl(location, url);
  			*rval = go_fetch(location, ui);
  		}
  		goto cleanup_fetch_url;
 Index: usr.bin/ftp/uri.c
 ===================================================================
 RCS file: usr.bin/ftp/uri.c
 diff -N usr.bin/ftp/uri.c
 --- /dev/null	1 Jan 1970 00:00:00 -0000
 +++ usr.bin/ftp/uri.c	27 Jun 2026 05:01:07 -0000
 @@ -0,0 +1,313 @@
 +/*	$NetBSD: $	*/
 +
 +/*-
 + * Copyright (c) 2026 The NetBSD Foundation, Inc.
 + * All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 + * POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#include <stdlib.h>
 +#include <string.h>
 +
 +#include "ssl.h"
 +#include "ftp_var.h"
 +#include "uri.h"
 +
 +typedef struct {
 +	const char *buf;
 +	size_t scheme;
 +	size_t authority;
 +	size_t path;
 +	size_t query;
 +	size_t fragment;
 +} uriparts_t;
 +
 +#define SCHEME(p) ((p)->buf)
 +#define AUTHORITY(p) (SCHEME(p) + (p)->scheme)
 +#define PATH(p) (AUTHORITY(p) + (p)->authority)
 +#define QUERY(p) (PATH(p) + (p)->path)
 +#define FRAGMENT(p) (QUERY(p) + (p)->query)
 +
 +static void
 +split_uri(const char *uri, uriparts_t *parts)
 +{
 +	char *colon, *slash, *query, *sharp;
 +
 +	parts->buf = uri;
 +	parts->scheme = 0;
 +	parts->authority = 0;
 +	parts->path = 0;
 +	parts->query = 0;
 +	parts->fragment = 0;
 +
 +	colon = strchr(uri, ':');
 +	slash = strchr(uri, '/');
 +	if (colon && (slash == NULL || (colon - uri) < (slash - uri))) {
 +		parts->scheme = colon + 1 - uri;
 +		uri = colon + 1;
 +	}       
 +
 +	if (uri[0] == '/' && uri[1] == '/') {
 +		slash = strchr(uri + 2, '/');
 +		if (slash == NULL) {
 +			parts->authority = strlen(uri); 
 +			return;
 +		}
 +		parts->authority = slash - uri;
 +		uri = slash;
 +	}       
 +
 +	query = strchr(uri, '?');
 +	sharp = strchr(uri, '#');
 +	if (query && (sharp == NULL || (query - uri) < (sharp - uri))) {
 +		parts->path = query - uri;
 +		uri = query;
 +		if (sharp != NULL) {
 +			parts->query = sharp - query;
 +			parts->fragment = strlen(sharp);
 +			return;
 +		}
 +		parts->query = strlen(query);
 +		return;
 +	}
 +
 +	if (sharp != NULL) {
 +		parts->path = sharp - uri;
 +		parts->fragment = strlen(sharp);
 +		return;
 +	}
 +
 +	parts->path = strlen(uri);
 +}
 +
 +static char *
 +build_uri(uriparts_t *s, uriparts_t *a, uriparts_t *p,
 +    uriparts_t *q, uriparts_t *f)
 +{
 +	size_t len;
 +	char *buf, *out;
 +
 +	len = s->scheme + a->authority + p->path + q->query + f->fragment;
 +	buf = ftp_malloc(len + 1);
 +
 +	out = buf;
 +	memcpy(out, SCHEME(s), s->scheme);
 +	out += s->scheme;
 +	memcpy(out, AUTHORITY(a), a->authority);
 +	out += a->authority;
 +	memcpy(out, PATH(p), p->path);
 +	out += p->path;
 +	memcpy(out, QUERY(q), q->query);
 +	out += q->query;
 +	memcpy(out, FRAGMENT(f), f->fragment);
 +	out += f->fragment;
 +	*out = '\0';
 +
 +	return buf;
 +}
 +
 +static char *
 +remove_dot_segments(const char *path, size_t len)
 +{
 +	char *p;
 +	char *buf, *out, *seg;
 +	size_t n;
 +
 +	p = ftp_malloc(len + 1);
 +	strcpy(p, path);
 +
 +	buf = ftp_malloc(len + 1);
 +	out = buf;
 +	*out = '\0';
 +
 +	while (len > 0) {
 +		/* A */
 +		if (p[0] == '.') {
 +			if (len > 1 && p[1] == '/') {
 +				p += 2;
 +				len -= 2;
 +				continue;
 +			} else if (len > 2 && p[1] == '.' && p[2] == '/') {
 +				p += 3;
 +				len -= 3;
 +				continue;
 +			}
 +		}
 +
 +		/* B */
 +		if (p[0] == '/') {
 +			if (len > 2 && p[1] == '.' && p[2] == '/') {
 +				p += 2;
 +				len -= 2;
 +				continue;
 +			} else if (len == 2 && p[1] == '.') {
 +				p += 1;
 +				len -= 1;
 +				p[0] = '/';
 +				continue;
 +			}
 +		}
 +
 +		/* C */
 +		if (len > 2 && p[0] == '/' && p[1] == '.' && p[2] == '.') {
 +			if (len > 3 && p[3] == '/') {
 +				p += 3;
 +				len -= 3;
 +				seg = strrchr(buf, '/');
 +				if (seg != NULL)
 +					*seg = '\0';
 +				continue;
 +			} else if (len == 3) {
 +				p += 2;
 +				len -= 2;
 +				p[0] = '/';
 +				seg = strrchr(buf, '/');
 +				if (seg != NULL)
 +					*seg = '\0';
 +				continue;
 +			}
 +		}
 +
 +		/* D */
 +		if (p[0] == '.') {
 +			if (len == 1) {
 +				p += 1;
 +				len -= 1;
 +				continue;
 +			} else if (len == 2 && p[1] == '.') {
 +				p += 2;
 +				len -= 2;
 +				continue;
 +			}
 +		}
 +
 +		/* E */
 +		if (p[0] == '/') {
 +			seg = strchr(p+1, '/');
 +		} else {
 +			seg = strchr(p, '/');
 +		}
 +		if (seg != NULL)
 +			n = seg - p;
 +		else
 +			n = len;
 +
 +		memcpy(out, p, n);
 +		out += n;
 +		*out = '\0';
 +		p += n;
 +		len -= n;
 +	};
 +
 +	FREEPTR(p);
 +
 +	return buf;
 +}
 +
 +static char *
 +merge_paths(uriparts_t *base, uriparts_t *ref)
 +{
 +	char *buf;
 +	const char *path, *last;
 +	size_t len;
 +
 +	if (base->authority && base->path == 0) {
 +		len = 1 + ref->path;
 +		buf = ftp_malloc(len + 1);
 +		buf[0] = '/';
 +		memcpy(buf + 1, PATH(ref), ref->path);
 +	} else {
 +		path = PATH(base);
 +		last = strrchr(path, '/');
 +		if (last == NULL || (size_t)(last - path) > base->path)
 +			len = 0;
 +		else
 +			len = (size_t)(last - path) + 1;
 +		buf = ftp_malloc(len + ref->path + 1);
 +		memcpy(buf, path, len);
 +		memcpy(buf + len, PATH(ref), ref->path);
 +		len += ref->path;
 +	}
 +	buf[len] = '\0';
 +
 +	return buf;
 +}
 +
 +char *
 +make_absurl(char *refurl, const char *baseurl)
 +{
 +	uriparts_t base;
 +	uriparts_t ref;
 +	uriparts_t p;
 +	char *buf, *tmp1, *tmp2;
 +	
 +	split_uri(baseurl, &base);
 +	split_uri(refurl, &ref);
 +
 +	p.scheme = p.authority = p.path = p.query = p.fragment = 0;
 +
 +	if (ref.scheme) {
 +		tmp1 = remove_dot_segments(PATH(&ref), ref.path);
 +		p.buf = tmp1;
 +		p.path = strlen(tmp1);
 +		buf = build_uri(&ref, &ref, &p, &ref, &ref);
 +		FREEPTR(tmp1);
 +	} else {
 +		if (ref.authority) {
 +			tmp1 = remove_dot_segments(PATH(&ref), ref.path);
 +			p.buf = tmp1;
 +			p.path = strlen(tmp1);
 +			buf = build_uri(&base, &ref, &p, &ref, &ref);
 +			FREEPTR(tmp1);
 +		} else {
 +			if (ref.path == 0) {
 +				if (ref.query) {
 +					buf = build_uri(&base, &base, &base, &ref, &ref);
 +				} else {
 +					buf = build_uri(&base, &base, &base, &base, &ref);
 +				}
 +			} else {
 +				if (PATH(&ref)[0] == '/') {
 +					tmp1 = remove_dot_segments(PATH(&ref), ref.path);
 +					p.buf = tmp1;
 +					p.path = strlen(tmp1);
 +					buf = build_uri(&base, &base, &p, &ref, &ref);
 +					FREEPTR(tmp1);
 +				} else {
 +					tmp2 = merge_paths(&base, &ref);
 +					tmp1 = remove_dot_segments(tmp2, strlen(tmp2));
 +					p.buf = tmp1;
 +					p.path = strlen(tmp1);
 +					FREEPTR(tmp2);
 +
 +					buf = build_uri(&base, &base, &p, &ref, &ref);
 +					FREEPTR(tmp1);
 +				}
 +			}
 +		}
 +	}
 +
 +	FREEPTR(refurl);
 +
 +	return buf;
 +}
 Index: usr.bin/ftp/uri.h
 ===================================================================
 RCS file: usr.bin/ftp/uri.h
 diff -N usr.bin/ftp/uri.h
 --- /dev/null	1 Jan 1970 00:00:00 -0000
 +++ usr.bin/ftp/uri.h	27 Jun 2026 05:01:07 -0000
 @@ -0,0 +1,29 @@
 +/*	$NetBSD: $	*/
 +
 +/*-
 + * Copyright (c) 2026 The NetBSD Foundation, Inc.
 + * All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 + * POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +char *make_absurl(char *, const char *);

From: "Michael van Elst" <mlelstv@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60346 CVS commit: src/usr.bin/ftp
Date: Mon, 6 Jul 2026 07:07:01 +0000

 Module Name:	src
 Committed By:	mlelstv
 Date:		Mon Jul  6 07:07:00 UTC 2026

 Modified Files:
 	src/usr.bin/ftp: Makefile fetch.c
 Added Files:
 	src/usr.bin/ftp: uri.c uri.h

 Log Message:
 Evaluate relative URLs in a HTTP redirect.

 Fixes PR 60346


 To generate a diff of this commit:
 cvs rdiff -u -r1.45 -r1.46 src/usr.bin/ftp/Makefile
 cvs rdiff -u -r1.246 -r1.247 src/usr.bin/ftp/fetch.c
 cvs rdiff -u -r0 -r1.1 src/usr.bin/ftp/uri.c src/usr.bin/ftp/uri.h

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Patrick Welche <prlw1@welche.eu>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Wed, 8 Jul 2026 13:16:13 +0100

 I have started seeing segmentation faults - maybe related?

 Easiest is the reproducer:

 gdb `which ftp`
 run https://github.com/openmm/openmm/archive/8.5.2.tar.gz


 (gdb) run https://github.com/openmm/openmm/archive/8.5.2.tar.gz
 Starting program: /usr/bin/ftp https://github.com/openmm/openmm/archive/8.5.2.tar.gz
 Requesting https://github.com/openmm/openmm/archive/8.5.2.tar.gz
 Redirected to https://codeload.github.com/openmm/openmm/tar.gz/refs/tags/8.5.2

 Program received signal SIGSEGV, Segmentation fault.
 0x00007f7ff752ace6 in strcmp () from /usr/lib/libc.so.12
 (gdb) bt
 #0  0x00007f7ff752ace6 in strcmp () from /usr/lib/libc.so.12
 #1  0x00007f7ff7a85446 in query_cmp (a=0x7f7ff71f3ff0, b=0x7f7fffffc300)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/property/property.c:194
 #2  0x00007f7ff7a99871 in getrn (lh=0x7f7ff71f88c0, data=0x7f7fffffc300, 
     rhash=rhash@entry=0x7f7fffffc2d8)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/lhash/lhash.c:344
 #3  0x00007f7ff7a99dca in OPENSSL_LH_retrieve (lh=<optimized out>, 
     data=data@entry=0x7f7fffffc300)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/lhash/lhash.c:180
 #4  0x00007f7ff7a8603c in lh_QUERY_retrieve (lh=<optimized out>, 
     d=0x7f7fffffc300)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/property/property.c:57
 ...
 #17 0x00000000000215d3 in fetch_start_ssl (sock=sock@entry=8, 
     servername=servername@entry=0x7f7ff71ca6e0 "codeload.github.com")
     at /usr/src/usr.bin/ftp/ssl.c:674
 #18 0x0000000000012509 in ftp_socket (ui=0x7f7fffffcaf0, ssl=0x7f7fffffca28, 
     auth=0x7f7fffffcab0) at /usr/src/usr.bin/ftp/fetch.c:717
 #19 fetch_url (
     url=url@entry=0x7f7ff72b59b0 "https://codeload.github.com/openmm/openmm/tar.gz/refs/tags/8.5.2", proxyenv=proxyenv@entry=0x0, 
     proxyauth=proxyauth@entry=0x0, wwwauth=wwwauth@entry=0x0, 
     rui=rui@entry=0x7f7fffffd750) at /usr/src/usr.bin/ftp/fetch.c:1576
 #20 0x0000000000014da0 in go_fetch (
     url=url@entry=0x7f7ff72b59b0 "https://codeload.github.com/openmm/openmm/tar.gz/refs/tags/8.5.2", rui=rui@entry=0x7f7fffffd750)
     at /usr/src/usr.bin/ftp/fetch.c:2370
 #21 0x000000000001480e in negotiate_connection (fin=0x7f7ff7302840, 
     url=0x7f7fffffecbd "https://github.com/openmm/openmm/archive/8.5.2.tar.gz", penv=0x7f7ff7331208 "", pi=<synthetic pointer>, mtime=0x7f7fffffd680, 
     wauth=0x7f7fffffd710, pauth=0x7f7fffffd730, rval=0x7f7fffffd5f8, 
     ischunked=0x7f7fffffd5fc, auth=0x7f7fffffd638, ui=0x7f7fffffd750)
     at /usr/src/usr.bin/ftp/fetch.c:1251
 ...

From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Wed, 8 Jul 2026 14:48:17 +0200

 On Wed, Jul 08, 2026 at 12:20:01PM +0000, Patrick Welche via gnats wrote:
 >  I have started seeing segmentation faults - maybe related?
 >  
 >  Easiest is the reproducer:
 >  
 >  gdb `which ftp`
 >  run https://github.com/openmm/openmm/archive/8.5.2.tar.gz

 It does work for me in -current.
 Are you by chance on netbsd-11 and not quite up-to-date?

 Martin

From: Michael van Elst <mlelstv@serpens.de>
To: gnats-bugs@netbsd.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Wed, 8 Jul 2026 15:38:39 +0200

 On Wed, Jul 08, 2026 at 12:20:01PM +0000, Patrick Welche via gnats wrote:

 >  gdb `which ftp`
 >  run https://github.com/openmm/openmm/archive/8.5.2.tar.gz


 >  #17 0x00000000000215d3 in fetch_start_ssl (sock=sock@entry=8, 
 >      servername=servername@entry=0x7f7ff71ca6e0 "codeload.github.com")
 >      at /usr/src/usr.bin/ftp/ssl.c:674


 On amd64-current:

 Program received signal SIGSEGV, Segmentation fault.
 0x000079ccc1a7cce6 in strcmp () from /usr/lib/libc.so.12
 (gdb) where
 #0  0x000079ccc1a7cce6 in strcmp () from /usr/lib/libc.so.12
 #1  0x000079ccc1fd9446 in query_cmp (a=0x79ccc17c4020, b=0x7f7fff846990)
     at /scratch/netbsd-current/src/crypto/external/apache2/openssl/dist/crypto/property/property.c:194


 The segfault is trying to deference a pointer with the value "gz/refs".


 So that's probably a buffer overflow somewhere. I have a look.


From: Patrick Welche <prlw1@welche.eu>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Wed, 8 Jul 2026 14:40:35 +0100

 On Wed, Jul 08, 2026 at 12:50:02PM +0000, Martin Husemann via gnats wrote:
 >  It does work for me in -current.
 >  Are you by chance on netbsd-11 and not quite up-to-date?

 It's -current/amd64 with source from Jul 8 10:15 UTC. I updated to get
 the ld.elf_so/load.c change.

 Admitedly it was a MKUPATE=yes update.

 I'll have another go with an empty /usr/obj on the off-chance...
 Updating I get a new libevent...

From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Wed, 8 Jul 2026 16:16:59 -0000 (UTC)

 gnats-admin@NetBSD.org ("Patrick Welche via gnats") writes:

 > I have started seeing segmentation faults - maybe related?
 > 
 > Easiest is the reproducer:
 > 
 > gdb `which ftp`
 > run https://github.com/openmm/openmm/archive/8.5.2.tar.gz


 Silly bug (of mine) like:

 p = malloc();
 p += advance;
 free(p);

 Please cvs up.

From: Patrick Welche <prlw1@welche.eu>
To: gnats-bugs@netbsd.org
Cc: mlelstv@serpens.de
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Wed, 8 Jul 2026 18:23:47 +0100

 On Wed, Jul 08, 2026 at 04:20:02PM +0000, Michael van Elst via gnats wrote:
 > The following reply was made to PR bin/60346; it has been noted by GNATS.
 >
 > From: mlelstv@serpens.de (Michael van Elst)
 > To: gnats-bugs@netbsd.org
 > Cc:
 > Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
 > Date: Wed, 8 Jul 2026 16:16:59 -0000 (UTC)
 >
 >  gnats-admin@NetBSD.org ("Patrick Welche via gnats") writes:
 >
 >  > I have started seeing segmentation faults - maybe related?
 >  >
 >  > Easiest is the reproducer:
 >  >
 >  > gdb `which ftp`
 >  > run https://github.com/openmm/openmm/archive/8.5.2.tar.gz
 >
 >
 >  Silly bug (of mine) like:
 >
 >  p = malloc();
 >  p += advance;
 >  free(p);
 >
 >  Please cvs up.

 Thanks for fixing it so quickly!

 # make mdi
 => Bootstrap dependency digest>=20211023: found digest-20220214
 => Fetching openmm-8.5.2.tar.gz
 Requesting https://github.com/openmm/openmm/archive/8.5.2.tar.gz
 Redirected to https://codeload.github.com/openmm/openmm/tar.gz/refs/tags/8.5.2
 Requesting https://codeload.github.com/openmm/openmm/tar.gz/refs/tags/8.5.2
  20700 KiB    3.83 MiB/s

 with /usr/bin/ftp

From: Ryo ONODERA <ryo@tetera.org>
To: mlelstv@serpens.de
Cc: gnats-bugs@netbsd.org
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Thu, 9 Jul 2026 02:51:22 +0900

 Hi,

 Your fix does not solve my problem yet sadly.
 I have a problem in pkgsrc/multimedia/libva.
 Could you take a look my problem too?

 libva package invokes /usr/bin/ftp like as follows:

 ryoon@castella: ~/tmp/ftp
 $ ftp https://github.com/intel/libva/releases/download/2.24.1/libva-2.24.1.=
 tar.bz2

 ryoon@castella: ~/tmp/ftp
 $ gdb /usr/bin/ftp ftp.core
 GNU gdb (GDB) 17.1
 Copyright (C) 2025 Free Software Foundation, Inc.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.htm=
 l>
 This is free software: you are free to change and redistribute it.
 There is NO WARRANTY, to the extent permitted by law.
 Type "show copying" and "show warranty" for details.
 This GDB was configured as "x86_64--netbsd".
 Type "show configuration" for configuration details.
 For bug reporting instructions, please see:
 <https://www.gnu.org/software/gdb/bugs/>.
 Find the GDB manual and other documentation resources online at:
     <http://www.gnu.org/software/gdb/documentation/>.

 For help, type "help".
 Type "apropos word" to search for commands related to "word"...
 Reading symbols from /usr/bin/ftp...
 Reading symbols from /usr/libdata/debug/usr/bin/ftp.debug...
 [New process 1300]
 Core was generated by `ftp'.
 Program terminated with signal SIGSEGV, Segmentation fault.
 #0  0x00007052ac9899b2 in memcpy () from /usr/lib/libc.so.12
 (gdb) bt
 #0  0x00007052ac9899b2 in memcpy () from /usr/lib/libc.so.12
 #1  0x000000000019253f in remove_dot_segments (path=3D<optimized out>,
 len=3D<optimized out>) at /usr/src/usr.bin/ftp/uri.c:216
 #2  0x00000000001927bf in make_absurl (
     refurl=3Drefurl@entry=3D0x7052ac5f7000
 "https://release-assets.githubusercontent.com/github-production-release-ass=
 et/16745233/af00959a-1177-46aa-a834-650739b8afaa?sp=3Dr&sv=3D2018-11-09&sr=
 =3Db&spr=3Dhttps&se=3D2026-07-08T18%3A28%3A37Z&rscd=3Dattachment"...,
     baseurl=3Dbaseurl@entry=3D0x7f7fff4a2dfc
 "https://github.com/intel/libva/releases/download/2.24.1/libva-2.24.1.tar.b=
 z2")
 at /usr/src/usr.bin/ftp/uri.c:271
 #3  0x00000000001897fc in negotiate_connection (fin=3D0x7052ac762840,
 url=3D0x7f7fff4a2dfc
 "https://github.com/intel/libva/releases/download/2.24.1/libva-2.24.1.tar.b=
 z2",
     penv=3D0x7052ac78e100
 "/github-production-release-asset/16745233/af00959a-1177-46aa-a834-650739b8=
 afaa?s/github-production-release-asset/16745233/af00959a-1177-46aa-a834-650=
 739b8afaa?s/github-production-release-asset/1674523"...,
 pi=3D<synthetic pointer>, mtime=3D0x7f7fff4a1790, wauth=3D0x7f7fff4a1820,
 pauth=3D0x7f7fff4a1840, rval=3D0x7f7fff4a1708,
     ischunked=3D0x7f7fff4a170c, auth=3D0x7f7fff4a1748, ui=3D0x7f7fff4a1860)
 at /usr/src/usr.bin/ftp/fetch.c:1250
 #4  fetch_url (url=3D0x7f7fff4a2dfc
 "https://github.com/intel/libva/releases/download/2.24.1/libva-2.24.1.tar.b=
 z2",
 proxyenv=3Dproxyenv@entry=3D0x0, proxyauth=3Dproxyauth@entry=3D0x0,
     wwwauth=3Dwwwauth@entry=3D0x0, rui=3Drui@entry=3D0x0) at
 /usr/src/usr.bin/ftp/fetch.c:1635
 #5  0x0000000000189da0 in go_fetch (url=3D<optimized out>,
 rui=3Drui@entry=3D0x0) at /usr/src/usr.bin/ftp/fetch.c:2370
 #6  0x000000000018a1dc in auto_fetch (argc=3D1, argv=3D0x7f7fff4a27f0) at
 /usr/src/usr.bin/ftp/fetch.c:2413
 #7  0x0000000000197837 in main (argc=3D<optimized out>, argv=3D<optimized
 out>) at /usr/src/usr.bin/ftp/main.c:550
 (gdb)

 On Thu, Jul 9, 2026 at 2:25=E2=80=AFAM Patrick Welche via gnats
 <gnats-admin@netbsd.org> wrote:
 >
 > The following reply was made to PR bin/60346; it has been noted by GNATS.
 >
 > From: Patrick Welche <prlw1@welche.eu>
 > To: gnats-bugs@netbsd.org
 > Cc: mlelstv@serpens.de
 > Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
 > Date: Wed, 8 Jul 2026 18:23:47 +0100
 >
 >  On Wed, Jul 08, 2026 at 04:20:02PM +0000, Michael van Elst via gnats wro=
 te:
 >  > The following reply was made to PR bin/60346; it has been noted by GNA=
 TS.
 >  >
 >  > From: mlelstv@serpens.de (Michael van Elst)
 >  > To: gnats-bugs@netbsd.org
 >  > Cc:
 >  > Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
 >  > Date: Wed, 8 Jul 2026 16:16:59 -0000 (UTC)
 >  >
 >  >  gnats-admin@NetBSD.org ("Patrick Welche via gnats") writes:
 >  >
 >  >  > I have started seeing segmentation faults - maybe related?
 >  >  >
 >  >  > Easiest is the reproducer:
 >  >  >
 >  >  > gdb `which ftp`
 >  >  > run https://github.com/openmm/openmm/archive/8.5.2.tar.gz
 >  >
 >  >
 >  >  Silly bug (of mine) like:
 >  >
 >  >  p =3D malloc();
 >  >  p +=3D advance;
 >  >  free(p);
 >  >
 >  >  Please cvs up.
 >
 >  Thanks for fixing it so quickly!
 >
 >  # make mdi
 >  =3D> Bootstrap dependency digest>=3D20211023: found digest-20220214
 >  =3D> Fetching openmm-8.5.2.tar.gz
 >  Requesting https://github.com/openmm/openmm/archive/8.5.2.tar.gz
 >  Redirected to https://codeload.github.com/openmm/openmm/tar.gz/refs/tags=
 /8.5.2
 >  Requesting https://codeload.github.com/openmm/openmm/tar.gz/refs/tags/8.=
 5.2
 >   20700 KiB    3.83 MiB/s
 >
 >  with /usr/bin/ftp
 >


 --=20
 Ryo ONODERA // ryo@tetera.org
 PGP fingerprint =3D 82A2 DC91 76E0 A10A 8ABB  FD1B F404 27FA C7D1 15F3

From: Michael van Elst <mlelstv@serpens.de>
To: gnats-bugs@netbsd.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Wed, 8 Jul 2026 21:30:06 +0200

 On Wed, Jul 08, 2026 at 05:55:01PM +0000, Ryo ONODERA via gnats wrote:
 > The following reply was made to PR bin/60346; it has been noted by GNATS.
 > 
 > From: Ryo ONODERA <ryo@tetera.org>
 > To: mlelstv@serpens.de
 > Cc: gnats-bugs@netbsd.org
 > Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
 > Date: Thu, 9 Jul 2026 02:51:22 +0900
 > 
 >  Hi,
 >  
 >  Your fix does not solve my problem yet sadly.
 >  I have a problem in pkgsrc/multimedia/libva.
 >  Could you take a look my problem too?

 Thanks for noticing...

 The search for a path segment separator has to stop at the end of the path,
 not at the end of the buffer.


 Gretings,
 -- 
                                 Michael van Elst
 Internet: mlelstv@serpens.de
                                 "A potential Snark may lurk in every tree."

From: Ryo ONODERA <ryo@tetera.org>
To: mlelstv@serpens.de, gnats-bugs@netbsd.org
Cc: 
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Fri, 10 Jul 2026 00:22:39 +0900

 Hi,

 Michael van Elst <mlelstv@serpens.de> writes:

 > On Wed, Jul 08, 2026 at 05:55:01PM +0000, Ryo ONODERA via gnats wrote:
 >> The following reply was made to PR bin/60346; it has been noted by GNATS.
 >> 
 >> From: Ryo ONODERA <ryo@tetera.org>
 >> To: mlelstv@serpens.de
 >> Cc: gnats-bugs@netbsd.org
 >> Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
 >> Date: Thu, 9 Jul 2026 02:51:22 +0900
 >> 
 >>  Hi,
 >>  
 >>  Your fix does not solve my problem yet sadly.
 >>  I have a problem in pkgsrc/multimedia/libva.
 >>  Could you take a look my problem too?
 >
 > Thanks for noticing...
 >
 > The search for a path segment separator has to stop at the end of the path,
 > not at the end of the buffer.

 Your fix works for libva.
 However I have another problem during updating fonts/fontconfig.

 $ ftp https://gitlab.freedesktop.org/api/v4/projects/890/packages/generic/fontconfig/2.18.2/fontconfig-2.18.2.tar.xz
 Trying [2a04:4e42:200::820]:443 ...
 Requesting https://gitlab.freedesktop.org/api/v4/projects/890/packages/generic/fontconfig/2.18.2/fontconfig-2.18.2.tar.xz
 Redirected to https://fsn1.your-objectstorage.com/fdo-gitlab-packages/e6/f0/e6f095e985e6762f1538b47ff1abda58dbe8ce088b16d8a5744fc179e9a2fc16/%40final/0b/67/a2de0834c605ab6e44f49f2cbd0a76a61b74b6c14facc036b7246c790b04?response-content-disposition=attachment%3B%20filename%3D%22fontconfig-2.18.2.tar.xz%22%3B%20filename%2A%3DUTF-8%27%27fontconfig-2.18.2.tar.xz&response-content-type=application%2Fx-xz&X-Amz-Expires=600&X-Amz-Date=20260709T152153Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=HUZAP6VQ6FOSXT1W3SLF%2F20260709%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature=5c8470ccc68f270fc729edea69da15b299fb696847c089eedbde75aa2e46a616
 Trying [2a01:4f8:b001::1]:443 ...
 zsh: segmentation fault (core dumped)  ftp

 Could you take a look at my problem again?

 Thank you.

 > Gretings,
 > -- 
 >                                 Michael van Elst
 > Internet: mlelstv@serpens.de
 >                                 "A potential Snark may lurk in every tree."

 -- 
 Ryo ONODERA // ryo@tetera.org
 PGP fingerprint = 82A2 DC91 76E0 A10A 8ABB  FD1B F404 27FA C7D1 15F3

From: Ryo ONODERA <ryo@tetera.org>
To: gnats-bugs@netbsd.org, mlelstv@serpens.de
Cc: 
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Fri, 10 Jul 2026 01:29:36 +0900

 Hi,

 I had not included a backtrace. I am sorry.

 $ gdb /usr/bin/ftp ftp.core                                                     GNU gdb (GDB) 17.1
 Copyright (C) 2025 Free Software Foundation, Inc.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 This is free software: you are free to change and redistribute it.
 There is NO WARRANTY, to the extent permitted by law.
 Type "show copying" and "show warranty" for details.
 This GDB was configured as "x86_64--netbsd".
 Type "show configuration" for configuration details.
 For bug reporting instructions, please see:
 <https://www.gnu.org/software/gdb/bugs/>.
 Find the GDB manual and other documentation resources online at:
     <http://www.gnu.org/software/gdb/documentation/>.

 For help, type "help".
 Type "apropos word" to search for commands related to "word"...
 Reading symbols from /usr/bin/ftp...
 Reading symbols from /usr/libdata/debug/usr/bin/ftp.debug...
 [New process 15187]
 Core was generated by `ftp'.
 Program terminated with signal SIGSEGV, Segmentation fault.
 #0  OPENSSL_strcasecmp (
     s1=0x443325656d616e65 <error: Cannot access memory at address 0x443325656d616e65>, s2=0x791f865103cb "DER")
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/o_str.c:424
 424         while ((t = ossl_tolower(*s1) - ossl_tolower(*s2++)) == 0)
 (gdb) bt
 #0  OPENSSL_strcasecmp (
     s1=0x443325656d616e65 <error: Cannot access memory at address 0x443325656d616e65>, s2=0x791f865103cb "DER")
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/o_str.c:424
 #1  0x0000791f8640760c in collect_decoder_keymgmt (keymgmt=<optimized out>,
     decoder=0x791f85aa7200, provctx=<optimized out>, data=<optimized out>)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/encode_decode/decoder_pkey.c:268
 #2  collect_decoder (decoder=0x791f85aa7200, arg=0x7f7fff2d43d0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/encode_decode/decoder_pkey.c:353
 #3  0x0000791f8638dc98 in alg_do_one (alg=0x791f85a5ebe0,
     impl=<optimized out>, fn=0x791f86408490 <do_one>, fnarg=0x7f7fff2d42a0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/property/property.c:556
 #4  ossl_method_store_do_all (store=<optimized out>,
     fn=0x791f86408490 <do_one>, fnarg=0x7f7fff2d42a0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/property/property.c:606
 #5  0x0000791f8640905d in OSSL_DECODER_do_all_provided (
     libctx=libctx@entry=0x0,
     user_fn=user_fn@entry=0x791f8640753d <collect_decoder>,
     user_arg=user_arg@entry=0x7f7fff2d43d0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/encode_decode/decoder_meth.c:568
 #6  0x0000791f86407f41 in ossl_decoder_ctx_setup_for_pkey (ctx=0x791f85a9b260,
     keytype=0x7f7fff2d4530 "id-ecPublicKey", libctx=0x0, propquery=0x0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/encode_decode/decoder_pkey.c:524
 #7  OSSL_DECODER_CTX_new_for_pkey (pkey=pkey@entry=0x791f85a972b0,
     input_type=input_type@entry=0x791f865103cb "DER",
     input_structure=input_structure@entry=0x791f86510423 "SubjectPublicKeyInfo", keytype=keytype@entry=0x7f7fff2d4530 "id-ecPublicKey",
     selection=selection@entry=134, libctx=0x0, propquery=0x0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/encode_decode/decoder_pkey.c:890
 #8  0x0000791f86331629 in x509_pubkey_ex_d2i_ex (pval=<optimized out>,
     in=<optimized out>, len=<optimized out>, it=<optimized out>,
     tag=<optimized out>, aclass=0, opt=0 '\000', ctx=0x7f7fff2d49e0,
     libctx=0x0, propq=0x0)
 --Type <RET> for more, q to quit, c to continue without paging--
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/x509/x_pubkey.c:210
 #9  0x0000791f864e412a in asn1_item_embed_d2i (pval=pval@entry=0x791f85aa8650,
     in=in@entry=0x7f7fff2d46f0, len=<optimized out>, len@entry=678,
     it=0x791f8663ed20 <local_it>, tag=tag@entry=-1, aclass=aclass@entry=0,
     opt=opt@entry=0 '\000', ctx=ctx@entry=0x7f7fff2d49e0, depth=3,
     depth@entry=2, libctx=libctx@entry=0x0, propq=propq@entry=0x0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/asn1/tasn_dec.c:288
 #10 0x0000791f864e4e6a in asn1_template_noexp_d2i (val=0x791f85aa8650,
     in=0x7f7fff2d47c8, len=<optimized out>,
     tt=tt@entry=0x791f86679bb0 <X509_CINF_seq_tt+240>, opt=0 '\000',
     ctx=0x7f7fff2d49e0, depth=2, libctx=0x0, propq=0x0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/asn1/tasn_dec.c:709
 #11 0x0000791f864e5181 in asn1_template_ex_d2i (val=val@entry=0x791f85aa8650,
     in=in@entry=0x7f7fff2d47c8, inlen=inlen@entry=678,
     tt=tt@entry=0x791f86679bb0 <X509_CINF_seq_tt+240>, opt=<optimized out>,
     ctx=ctx@entry=0x7f7fff2d49e0, depth=<optimized out>, depth@entry=2,
     libctx=<optimized out>, libctx@entry=0x0, propq=<optimized out>,
     propq@entry=0x0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/asn1/tasn_dec.c:584
 #12 0x0000791f864e4484 in asn1_item_embed_d2i (pval=pval@entry=0x7f7fff2d4878,
     in=in@entry=0x7f7fff2d4880, len=<optimized out>, len@entry=962,
     it=0x791f8663eba0 <local_it>, tag=<optimized out>, tag@entry=-1,
     aclass=<optimized out>, aclass@entry=0, opt=opt@entry=0 '\000',
     ctx=ctx@entry=0x7f7fff2d49e0, depth=<optimized out>, depth@entry=1,
     libctx=libctx@entry=0x0, propq=propq@entry=0x0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/asn1/tasn_dec.c:448
 #13 0x0000791f864e4e6a in asn1_template_noexp_d2i (val=0x7f7fff2d4878,
     in=0x7f7fff2d4958, len=<optimized out>,
     tt=tt@entry=0x791f86679a40 <X509_seq_tt>, opt=0 '\000',
     ctx=0x7f7fff2d49e0, depth=1, libctx=0x0, propq=0x0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/asn1/tasn_dec.c:709
 #14 0x0000791f864e5181 in asn1_template_ex_d2i (val=val@entry=0x791f85aa8600,
     in=in@entry=0x7f7fff2d4958, inlen=inlen@entry=962,
     tt=tt@entry=0x791f86679a40 <X509_seq_tt>, opt=<optimized out>,
     ctx=ctx@entry=0x7f7fff2d49e0, depth=<optimized out>, depth@entry=1,
     libctx=<optimized out>, libctx@entry=0x0, propq=<optimized out>,
     propq@entry=0x0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/asn1/tasn_dec.c:584
 #15 0x0000791f864e4484 in asn1_item_embed_d2i (pval=pval@entry=0x7f7fff2d4a38,
     in=<optimized out>, len=<optimized out>,
 --Type <RET> for more, q to quit, c to continue without paging--
     it=it@entry=0x791f8663eb60 <local_it>, tag=<optimized out>, tag@entry=-1,
     aclass=<optimized out>, aclass@entry=0, opt=opt@entry=0 '\000',
     ctx=ctx@entry=0x7f7fff2d49e0, depth=<optimized out>, depth@entry=0,
     libctx=libctx@entry=0x0, propq=propq@entry=0x0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/asn1/tasn_dec.c:448
 #16 0x0000791f864e4af1 in asn1_item_ex_d2i_intern (pval=<optimized out>,
     in=<optimized out>, len=<optimized out>, it=<optimized out>,
     tag=<optimized out>, aclass=<optimized out>, opt=<optimized out>,
     ctx=<optimized out>, libctx=<optimized out>, propq=<optimized out>)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/asn1/tasn_dec.c:143
 #17 ASN1_item_d2i_ex (pval=<optimized out>, pval@entry=0x7f7fff2d4a38,
     in=in@entry=0x7f7fff2d4a40, len=len@entry=966,
     it=0x791f8663eb60 <local_it>, libctx=libctx@entry=0x0,
     propq=propq@entry=0x0)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/asn1/tasn_dec.c:169
 #18 0x0000791f864e4b5f in ASN1_item_d2i (pval=pval@entry=0x7f7fff2d4a38,
     in=in@entry=0x7f7fff2d4a40, len=len@entry=966, it=<optimized out>)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/asn1/tasn_dec.c:180
 #19 0x0000791f86330770 in d2i_X509 (a=a@entry=0x7f7fff2d4a38,
     in=in@entry=0x7f7fff2d4a40, len=len@entry=966)
     at /usr/src/crypto/external/apache2/openssl/dist/crypto/x509/x_x509.c:132
 #20 0x0000791f866ef0d0 in tls_process_server_certificate (s=0x791f85ae2800,
     pkt=0x7f7fff2d4ae0)
     at /usr/src/crypto/external/apache2/openssl/dist/ssl/statem/statem_clnt.c:2038
 #21 0x0000791f866f382a in read_state_machine (s=0x791f85ae2800)
     at /usr/src/crypto/external/apache2/openssl/dist/ssl/statem/statem.c:663
 #22 state_machine (s=0x791f85ae2800, server=0)
     at /usr/src/crypto/external/apache2/openssl/dist/ssl/statem/statem.c:481
 #23 0x00000000009a75d3 in fetch_start_ssl (sock=sock@entry=6,
     servername=servername@entry=0x791f85ad3b60 "fsn1.your-objectstorage.com")
     at /usr/src/usr.bin/ftp/ssl.c:674
 #24 0x0000000000998509 in ftp_socket (ui=0x7f7fff2d4e30, ssl=0x7f7fff2d4d68,
     auth=0x7f7fff2d4df0) at /usr/src/usr.bin/ftp/fetch.c:717
 #25 fetch_url (
     url=url@entry=0x791f85c16c00 "https://fsn1.your-objectstorage.com/fdo-gitlab-packages/e6/f0/e6f095e985e6762f1538b47ff1abda58dbe8ce088b16d8a5744fc179e9a2fc16/%40final/0b/67/a2de0834c605ab6e44f49f2cbd0a76a61b74b6c14facc036b7246c790b"..., proxyenv=proxyenv@entry=0x0, proxyauth=proxyauth@entry=0x0,
     wwwauth=wwwauth@entry=0x0, rui=rui@entry=0x7f7fff2d5a90)
 --Type <RET> for more, q to quit, c to continue without paging--
     at /usr/src/usr.bin/ftp/fetch.c:1576
 #26 0x000000000099ada0 in go_fetch (
     url=url@entry=0x791f85c16c00 "https://fsn1.your-objectstorage.com/fdo-gitlab-packages/e6/f0/e6f095e985e6762f1538b47ff1abda58dbe8ce088b16d8a5744fc179e9a2fc16/%40final/0b/67/a2de0834c605ab6e44f49f2cbd0a76a61b74b6c14facc036b7246c790b"..., rui=rui@entry=0x7f7fff2d5a90) at /usr/src/usr.bin/ftp/fetch.c:2370
 #27 0x000000000099a80e in negotiate_connection (fin=0x791f85c0d540,
     url=0x7f7fff2d708c "https://gitlab.freedesktop.org/api/v4/projects/890/packages/generic/fontconfig/2.18.2/fontconfig-2.18.2.tar.xz",
     penv=0x791f85c39100 "", pi=<synthetic pointer>, mtime=0x7f7fff2d59c0,
     wauth=0x7f7fff2d5a50, pauth=0x7f7fff2d5a70, rval=0x7f7fff2d5938,
     ischunked=0x7f7fff2d593c, auth=0x7f7fff2d5978, ui=0x7f7fff2d5a90)
     at /usr/src/usr.bin/ftp/fetch.c:1251
 #28 fetch_url (
     url=0x7f7fff2d708c "https://gitlab.freedesktop.org/api/v4/projects/890/packages/generic/fontconfig/2.18.2/fontconfig-2.18.2.tar.xz",
     proxyenv=proxyenv@entry=0x0, proxyauth=proxyauth@entry=0x0,
     wwwauth=wwwauth@entry=0x0, rui=rui@entry=0x0)
     at /usr/src/usr.bin/ftp/fetch.c:1635
 #29 0x000000000099ada0 in go_fetch (url=<optimized out>, rui=rui@entry=0x0)
     at /usr/src/usr.bin/ftp/fetch.c:2370
 #30 0x000000000099b1dc in auto_fetch (argc=1, argv=0x7f7fff2d6a20)
     at /usr/src/usr.bin/ftp/fetch.c:2413
 #31 0x00000000009a8857 in main (argc=<optimized out>, argv=<optimized out>)
     at /usr/src/usr.bin/ftp/main.c:550
 (gdb)

 -- 
 Ryo ONODERA // ryo@tetera.org
 PGP fingerprint = 82A2 DC91 76E0 A10A 8ABB  FD1B F404 27FA C7D1 15F3

From: Michael van Elst <mlelstv@serpens.de>
To: gnats-bugs@netbsd.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Thu, 9 Jul 2026 18:56:37 +0200

 On Thu, Jul 09, 2026 at 03:25:01PM +0000, Ryo ONODERA via gnats wrote:
 > The following reply was made to PR bin/60346; it has been noted by GNATS.
 > 
 >  However I have another problem during updating fonts/fontconfig.
 >  
 >  $ ftp https://gitlab.freedesktop.org/api/v4/projects/890/packages/generic/fontconfig/2.18.2/fontconfig-2.18.2.tar.xz

 Copying a length limited string segment with strcpy wasn't a good idea.


 -- 
                                 Michael van Elst
 Internet: mlelstv@serpens.de
                                 "A potential Snark may lurk in every tree."

From: Ryo ONODERA <ryo@tetera.org>
To: mlelstv@serpens.de, gnats-bugs@netbsd.org
Cc: 
Subject: Re: PR/60346 CVS commit: src/usr.bin/ftp
Date: Fri, 10 Jul 2026 12:52:58 +0900

 Hi,

 Michael van Elst <mlelstv@serpens.de> writes:

 > On Thu, Jul 09, 2026 at 03:25:01PM +0000, Ryo ONODERA via gnats wrote:
 >> The following reply was made to PR bin/60346; it has been noted by GNATS.
 >> 
 >>  However I have another problem during updating fonts/fontconfig.
 >>  
 >>  $ ftp https://gitlab.freedesktop.org/api/v4/projects/890/packages/generic/fontconfig/2.18.2/fontconfig-2.18.2.tar.xz
 >
 > Copying a length limited string segment with strcpy wasn't a good idea.

 Thank you very much.
 Your fix works fine for me now.

 > -- 
 >                                 Michael van Elst
 > Internet: mlelstv@serpens.de
 >                                 "A potential Snark may lurk in every tree."

 -- 
 Ryo ONODERA // ryo@tetera.org
 PGP fingerprint = 82A2 DC91 76E0 A10A 8ABB  FD1B F404 27FA C7D1 15F3

From: "Luke Mewburn" <lukem@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60346 CVS commit: src/usr.bin/ftp
Date: Sat, 18 Jul 2026 22:55:06 +0000

 Module Name:	src
 Committed By:	lukem
 Date:		Sat Jul 18 22:55:06 UTC 2026

 Modified Files:
 	src/usr.bin/ftp: version.h

 Log Message:
 ftp: version 20260718

 Fix -Wformat-overflow issues.
 Support relative URLs in HTTP Location redirection. PR bin/60346.
 Don't read off end of buffer when encoding authentication header.
 Forbid Location redirection to file://.


 To generate a diff of this commit:
 cvs rdiff -u -r1.104 -r1.105 src/usr.bin/ftp/version.h

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.