mirror of
				https://gitlab.freedesktop.org/libbsd/libbsd.git
				synced 2025-11-04 04:10:01 +01:00 
			
		
		
		
	Fix strnvis() and strnunvis() NetBSD ABI break
The NetBSD implementations have different prototypes to the ones coming from OpenBSD, which will break builds, and have caused segfaults at run-time. We provide now both interfaces with different prototypes as different version nodes allow selecting them at compile-time, defaulting for now to the OpenBSD one to avoid build-time breakage, while emitting a compile-time warning. Later on, in 0.10.0, we will be switching the compile-time default to the NetBSD version. Ref: http://gnats.netbsd.org/44977 Fixes: https://bugs.debian.org/899282
This commit is contained in:
		@@ -88,6 +88,22 @@
 | 
			
		||||
#include <bsd/sys/cdefs.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * NetBSD added an strnvis and unfortunately made it incompatible with the
 | 
			
		||||
 * existing one in OpenBSD and Freedesktop's libbsd (the former having existed
 | 
			
		||||
 * for over ten years). Despite this incompatibility being reported during
 | 
			
		||||
 * development (see http://gnats.netbsd.org/44977) they still shipped it.
 | 
			
		||||
 * Even more unfortunately FreeBSD and later MacOS picked up this incompatible
 | 
			
		||||
 * implementation.
 | 
			
		||||
 *
 | 
			
		||||
 * Provide both implementations and default for now on the historical one to
 | 
			
		||||
 * avoid breakage, we will switch to the NetBSD one in libbsd 0.10.0 or so.
 | 
			
		||||
 * Define LIBBSD_NETBSD_VIS to switch to the NetBSD one now.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LIBBSD_NETBSD_VIS
 | 
			
		||||
#warning "NetBSD added incompatible strnvis() and strnunvis(), please see <bsd/vis.h> for more detils."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
__BEGIN_DECLS
 | 
			
		||||
char	*vis(char *, int, int, int);
 | 
			
		||||
char	*nvis(char *, size_t, int, int, int);
 | 
			
		||||
@@ -97,7 +113,14 @@ char	*snvis(char *, size_t, int, int, int, const char *);
 | 
			
		||||
 | 
			
		||||
int	strvis(char *, const char *, int);
 | 
			
		||||
int	stravis(char **, const char *, int);
 | 
			
		||||
int	strnvis(char *, size_t, const char *, int);
 | 
			
		||||
#ifdef LIBBSD_NETBSD_VIS
 | 
			
		||||
/* NetBSD prototype. */
 | 
			
		||||
int	LIBBSD_REDIRECT(strnvis, (char *, size_t, const char *, int),
 | 
			
		||||
                        strnvis_netbsd);
 | 
			
		||||
#else
 | 
			
		||||
/* OpenBSD prototype (current default). */
 | 
			
		||||
int	strnvis(char *, const char *, size_t, int);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int	strsvis(char *, const char *, int, const char *);
 | 
			
		||||
int	strsnvis(char *, size_t, const char *, int, const char *);
 | 
			
		||||
@@ -112,7 +135,14 @@ int	strsenvisx(char *, size_t, const char *, size_t , int, const char *,
 | 
			
		||||
    int *);
 | 
			
		||||
 | 
			
		||||
int	strunvis(char *, const char *);
 | 
			
		||||
int	strnunvis(char *, size_t, const char *);
 | 
			
		||||
#ifdef LIBBSD_NETBSD_VIS
 | 
			
		||||
/* NetBSD prototype. */
 | 
			
		||||
int	LIBBSD_REDIRECT(strnunvis, (char *, size_t, const char *),
 | 
			
		||||
                        strnunvis_netbsd);
 | 
			
		||||
#else
 | 
			
		||||
/* OpenBSD prototype (current default). */
 | 
			
		||||
ssize_t	strnunvis(char *, const char *, size_t);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int	strunvisx(char *, const char *, int);
 | 
			
		||||
int	strnunvisx(char *, size_t, const char *, int);
 | 
			
		||||
 
 | 
			
		||||
@@ -160,3 +160,11 @@ LIBBSD_0.9 {
 | 
			
		||||
    strsvisx;
 | 
			
		||||
    svis;
 | 
			
		||||
} LIBBSD_0.8;
 | 
			
		||||
 | 
			
		||||
LIBBSD_0.9.1 {
 | 
			
		||||
    /* The strnvis() and strnunvis() symbols changed prototype to match
 | 
			
		||||
     * the NetBSD implementation. Provided as versioned nodes in 0.9.1, and
 | 
			
		||||
     * exposed here explicitly so that we can redirect at compile-time. */
 | 
			
		||||
    strnvis_netbsd;
 | 
			
		||||
    strnunvis_netbsd;
 | 
			
		||||
} LIBBSD_0.9;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								src/unvis.c
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/unvis.c
									
									
									
									
									
								
							@@ -37,7 +37,10 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wcpp"
 | 
			
		||||
#include <vis.h>
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
#ifdef __weak_alias
 | 
			
		||||
__weak_alias(strnunvisx,_strnunvisx)
 | 
			
		||||
@@ -543,8 +546,30 @@ strunvis(char *dst, const char *src)
 | 
			
		||||
	return strnunvisx(dst, (size_t)~0, src, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
strnunvis(char *dst, size_t dlen, const char *src)
 | 
			
		||||
/*
 | 
			
		||||
 * NetBSD added an strnvis and unfortunately made it incompatible with the
 | 
			
		||||
 * existing one in OpenBSD and Freedesktop's libbsd (the former having existed
 | 
			
		||||
 * for over ten years). Despite this incompatibility being reported during
 | 
			
		||||
 * development (see http://gnats.netbsd.org/44977) they still shipped it.
 | 
			
		||||
 * Even more unfortunately FreeBSD and later MacOS picked up this incompatible
 | 
			
		||||
 * implementation.
 | 
			
		||||
 *
 | 
			
		||||
 * Provide both implementations and default for now on the historical one to
 | 
			
		||||
 * avoid breakage, we will switch to the NetBSD one in libbsd 0.10.0 or so.
 | 
			
		||||
 *
 | 
			
		||||
 * OpenBSD, 2001: strnunvis(char *dst, const char *src, size_t dlen);
 | 
			
		||||
 * NetBSD: 2012,  strnunvis(char *dst, size_t dlen, const char *src);
 | 
			
		||||
 */
 | 
			
		||||
ssize_t
 | 
			
		||||
strnunvis_openbsd(char *dst, const char *src, size_t dlen)
 | 
			
		||||
{
 | 
			
		||||
	return strnunvisx(dst, dlen, src, 0);
 | 
			
		||||
}
 | 
			
		||||
__asm__(".symver strnunvis_openbsd,strnunvis@@LIBBSD_0.2");
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
strnunvis_netbsd(char *dst, size_t dlen, const char *src)
 | 
			
		||||
{
 | 
			
		||||
	return strnunvisx(dst, dlen, src, 0);
 | 
			
		||||
}
 | 
			
		||||
__asm__(".symver strnunvis_netbsd,strnunvis@LIBBSD_0.9.1");
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										27
									
								
								src/vis.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/vis.c
									
									
									
									
									
								
							@@ -60,7 +60,10 @@
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wcpp"
 | 
			
		||||
#include <vis.h>
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <wchar.h>
 | 
			
		||||
@@ -701,11 +704,33 @@ strvis(char *mbdst, const char *mbsrc, int flags)
 | 
			
		||||
	return istrsenvisxl(&mbdst, NULL, mbsrc, flags, "", NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * NetBSD added an strnvis and unfortunately made it incompatible with the
 | 
			
		||||
 * existing one in OpenBSD and Freedesktop's libbsd (the former having existed
 | 
			
		||||
 * for over ten years). Despite this incompatibility being reported during
 | 
			
		||||
 * development (see http://gnats.netbsd.org/44977) they still shipped it.
 | 
			
		||||
 * Even more unfortunately FreeBSD and later MacOS picked up this incompatible
 | 
			
		||||
 * implementation.
 | 
			
		||||
 *
 | 
			
		||||
 * Provide both implementations and default for now on the historical one to
 | 
			
		||||
 * avoid breakage, we will switch to the NetBSD one in libbsd 0.10.0 or so.
 | 
			
		||||
 *
 | 
			
		||||
 * OpenBSD, 2001: strnvis(char *dst, const char *src, size_t dlen, int flag);
 | 
			
		||||
 * NetBSD: 2012,  strnvis(char *dst, size_t dlen, const char *src, int flag);
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
strnvis(char *mbdst, size_t dlen, const char *mbsrc, int flags)
 | 
			
		||||
strnvis_openbsd(char *mbdst, const char *mbsrc, size_t dlen, int flags)
 | 
			
		||||
{
 | 
			
		||||
	return istrsenvisxl(&mbdst, &dlen, mbsrc, flags, "", NULL);
 | 
			
		||||
}
 | 
			
		||||
__asm__(".symver strnvis_openbsd,strnvis@@LIBBSD_0.2");
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
strnvis_netbsd(char *mbdst, size_t dlen, const char *mbsrc, int flags)
 | 
			
		||||
{
 | 
			
		||||
	return istrsenvisxl(&mbdst, &dlen, mbsrc, flags, "", NULL);
 | 
			
		||||
}
 | 
			
		||||
__asm__(".symver strnvis_netbsd,strnvis@LIBBSD_0.9.1");
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
stravis(char **mbdstp, const char *mbsrc, int flags)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								test/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								test/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -19,3 +19,5 @@ setmode
 | 
			
		||||
strl
 | 
			
		||||
strmode
 | 
			
		||||
strnstr
 | 
			
		||||
vis
 | 
			
		||||
vis-openbsd
 | 
			
		||||
 
 | 
			
		||||
@@ -47,6 +47,8 @@ check_PROGRAMS = \
 | 
			
		||||
	strl \
 | 
			
		||||
	strmode \
 | 
			
		||||
	strnstr \
 | 
			
		||||
	vis \
 | 
			
		||||
	vis-openbsd \
 | 
			
		||||
	$(nil)
 | 
			
		||||
 | 
			
		||||
if HAVE_LIBTESTU01
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								test/vis-openbsd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								test/vis-openbsd.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright © 2018 Guillem Jover <guillem@hadrons.org>
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 * 3. The name of the author may not be used to endorse or promote products
 | 
			
		||||
 *    derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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 <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wcpp"
 | 
			
		||||
#include <vis.h>
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	char str[200];
 | 
			
		||||
	char unstr[200];
 | 
			
		||||
 | 
			
		||||
	strnvis(str, "0123456789abcdef", 10, 0);
 | 
			
		||||
	assert(strcmp(str, "0123456789") == 0);
 | 
			
		||||
 | 
			
		||||
	strnunvis(unstr, str, 100);
 | 
			
		||||
	assert(strcmp(unstr, "0123456789") == 0);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								test/vis.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								test/vis.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright © 2018 Guillem Jover <guillem@hadrons.org>
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 * 3. The name of the author may not be used to endorse or promote products
 | 
			
		||||
 *    derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define LIBBSD_NETBSD_VIS 1
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <vis.h>
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	char str[200];
 | 
			
		||||
	char unstr[200];
 | 
			
		||||
 | 
			
		||||
	strnvis(str, 10, "0123456789abcdef", 0);
 | 
			
		||||
	assert(strcmp(str, "0123456789") == 0);
 | 
			
		||||
 | 
			
		||||
	strnunvis(unstr, 100, str);
 | 
			
		||||
	assert(strcmp(unstr, "0123456789") == 0);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user