Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src swab(3): Rewrite this to be understandable.



details:   https://anonhg.NetBSD.org/src/rev/9db298915448
branches:  trunk
changeset: 372817:9db298915448
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Wed Dec 28 15:34:19 2022 +0000

description:
swab(3): Rewrite this to be understandable.

And make the tests work, and exercise all lengths up to 100.

Evidently the previous definition, presumably tightly optimized for
1980s-era compilers and CPUs, was too hard to understand, because it
was incorrectly tested for two decades and broken for years.

PR lib/57141

XXX pullup-8
XXX pullup-9
XXX pullup-10

diffstat:

 lib/libc/string/swab.c         |  94 ++++++++++++++++++-----------------------
 tests/lib/libc/string/t_swab.c |  26 +++++++----
 2 files changed, 58 insertions(+), 62 deletions(-)

diffs (184 lines):

diff -r 7ba9ebf944f7 -r 9db298915448 lib/libc/string/swab.c
--- a/lib/libc/string/swab.c    Wed Dec 28 14:32:04 2022 +0000
+++ b/lib/libc/string/swab.c    Wed Dec 28 15:34:19 2022 +0000
@@ -1,11 +1,9 @@
-/*     $NetBSD: swab.c,v 1.19 2022/12/28 14:32:04 kre Exp $    */
+/*     $NetBSD: swab.c,v 1.20 2022/12/28 15:34:19 riastradh Exp $      */
+
 
-/*
- * Copyright (c) 1988, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jeffrey Mogul.
+/*-
+ * Copyright (c) 2022 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
@@ -15,66 +13,58 @@
  * 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. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ * 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 <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)swab.c     8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: swab.c,v 1.19 2022/12/28 14:32:04 kre Exp $");
+__RCSID("$NetBSD: swab.c,v 1.20 2022/12/28 15:34:19 riastradh Exp $");
 #endif
-#endif /* LIBC_SCCS and not lint */
 
 #include <assert.h>
 #include <unistd.h>
 
 void
-swab(const void * __restrict from, void * __restrict to, ssize_t len)
+swab(const void *__restrict src, void *__restrict dst, ssize_t nbytes)
 {
-       char temp;
-       const char *fp;
-       char *tp;
+       const char *p = src;
+       char *q = dst;
+       size_t n;
 
-       if (len <= 1)
+       _DIAGASSERT(src != NULL);
+       _DIAGASSERT(dst != NULL);
+
+       if (nbytes <= 1)
                return;
 
-       _DIAGASSERT(from != NULL);
-       _DIAGASSERT(to != NULL);
-
-       len /= 2;
-       fp = (const char *)from;
-       tp = (char *)to;
-#define        STEP    temp = *fp++,*tp++ = *fp++,*tp++ = temp
+       /*
+        * Round nbytes/2 down; we ignore the last byte altogether if
+        * nbytes is odd.  This way, if the destination array is
+        * uninitialized, sanitizers will recognize the last byte as
+        * still uninitialized and flag it as undefined.
+        */
+       for (n = nbytes/2; n --> 0; p += 2, q += 2) {
+               /*
+                * According to POSIX (2018), the behaviour is
+                * undefined if src and dst overlap.  However, there
+                * are uses in-tree (xsrc/external/mit/xfwp/dist/io.c)
+                * that rely on swab(ptr, ptr, n) to do the swabbing
+                * in-place.  So make sure this works if src == dst.
+                */
+               const char p0 = p[0], p1 = p[1];
 
-       if (__predict_false(len == 1)) {
-               STEP;
-               return;
-       }
-
-       /* round to multiple of 8 */
-       while ((len % 8) != 0)
-               len--, STEP;
-       len /= 8;
-       if (len == 0)
-               return;
-       while (len-- != 0) {
-               STEP; STEP; STEP; STEP;
-               STEP; STEP; STEP; STEP;
+               q[0] = p1;
+               q[1] = p0;
        }
 }
diff -r 7ba9ebf944f7 -r 9db298915448 tests/lib/libc/string/t_swab.c
--- a/tests/lib/libc/string/t_swab.c    Wed Dec 28 14:32:04 2022 +0000
+++ b/tests/lib/libc/string/t_swab.c    Wed Dec 28 15:34:19 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: t_swab.c,v 1.2 2011/07/07 08:27:36 jruoho Exp $ */
+/*     $NetBSD: t_swab.c,v 1.3 2022/12/28 15:34:19 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -39,15 +39,17 @@
 #define MAXCHK 100
 
 static void
-build(char *a, char *b, size_t n) {
+build(char *a, char *b, size_t n)
+{
        size_t i;
 
-       n >>= 1;
        for (i = 0; i < n; i += 2) {
-               b[i+1] = a[i] = (char)i;
-               b[i] = a[i+1] = (char)(i+1);
+               b[i + 1] = a[i] = (char)i;
+               b[i] = a[i + 1] = (char)(i + 1);
        }
-       for (n <<= 1; n < MAXCHK; n++)
+       if (n & 1)
+               a[n - 1] = b[n - 1] = (char)~1;
+       for (; n < MAXCHK; n++)
                a[n] = b[n] = (char)~0;
 }
 
@@ -72,19 +74,23 @@
 {
        char a[MAXCHK], b[MAXCHK], r[MAXCHK];
        size_t i;
+       bool failed = false;
 
-       for (i = 0; i < MAXCHK; i += 2) {
+       for (i = 0; i < MAXCHK; i++) {
                build(a, b, i);
                (void)memset(r, ~0, MAXCHK);
                swab(a, r, i);
+               if (i & 1)      /* last byte unspecified if odd length */
+                       r[i - 1] = (char )~1;
                if (memcmp(b, r, MAXCHK) != 0) {
-                       fprintf(stderr, "pattern mismatch at %lu bytes",
-                           (unsigned long)i);
+                       printf("pattern mismatch at %zu bytes\n", i);
                        dump("expect:", b, MAXCHK);
                        dump("result:", r, MAXCHK);
-                       atf_tc_fail("Check stderr for details");
+                       failed = true;
                }
        }
+       if (failed)
+               atf_tc_fail_nonfatal("Check stdout for details");
 }
 
 ATF_TP_ADD_TCS(tp)



Home | Main Index | Thread Index | Old Index