mirror of
https://gitlab.freedesktop.org/libbsd/libbsd.git
synced 2025-01-07 17:52:34 +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:
parent
bf697b900c
commit
e4e15ed286
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user