NetBSD Problem Report #59952

From www@netbsd.org  Sat Jan 31 02:27:23 2026
Return-Path: <www@netbsd.org>
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) server-digest SHA256
	 client-signature RSA-PSS (2048 bits) client-digest SHA256)
	(Client CN "mail.netbsd.org", Issuer "R13" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id C525E1A923D
	for <gnats-bugs@gnats.NetBSD.org>; Sat, 31 Jan 2026 02:27:23 +0000 (UTC)
Message-Id: <20260131022722.855B51A923E@mollari.NetBSD.org>
Date: Sat, 31 Jan 2026 02:27:22 +0000 (UTC)
From: adrian@freebsd.org
Reply-To: adrian@freebsd.org
To: gnats-bugs@NetBSD.org
Subject: xsetwallpaper: server/client endian mismatch
X-Send-Pr-Version: www-1.0
X-From4GNATS: "adrian@freebsd.org via gnats" <gnats-admin@NetBSD.org>

>Number:         59952
>Category:       xsrc
>Synopsis:       xsetwallpaper: server/client endian mismatch
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    xsrc-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jan 31 02:30:00 +0000 2026
>Last-Modified:  Wed Feb 11 00:10:02 +0000 2026
>Originator:     adrian chadd
>Release:        11.99.4
>Organization:
>Environment:
sgimips-r4000$ uname -a
NetBSD sgimips-r4000.home.cacheboy.io 11.99.4 NetBSD 11.99.4 (GENERIC32_IP2x) #0: Mon Jan 12 21:48:13 UTC 2026  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/sgimips/compile/GENERIC32_IP2x sgimips

>Description:
xsetwallpaper assumes the image byte order was decoded into host byte order. however if you run xsetwallpaper on mismatching endian computers - eg amd64 (le) client, sgimips (be) server, then things are corrupted.
>How-To-Repeat:
Do the above: run xsetwallpaper on a different endian client to server.
>Fix:
I did a quick diff that just sets image->byte_order to host endian order so the library/server knows what to do with it.

The alternative solution is to not re-swizzle the endian-ness of the image data and leave it as little-endian.

===

diff --git a/src/xsetwallpaper.c b/src/xsetwallpaper.c
index 8b20050..335acea 100644
--- a/src/xsetwallpaper.c
+++ b/src/xsetwallpaper.c
@@ -104,6 +104,8 @@ main(int argc, char *argv[])
                data[i + 2] = p;
        }

+       /* At this point it's little endian regardless of host type. */
+
 #if _BYTE_ORDER == _BIG_ENDIAN
        for (i = 0; i < imagew * imageh * 4; i += 4) {
                uint32_t *p = (uint32_t *)&data[i];
@@ -111,6 +113,8 @@ main(int argc, char *argv[])
        }
 #endif

+       /* It is now in host endian */
+
 #ifdef DEBUG
        printf("%s: %dx%d %dbpp\n", argv[0], imagew, imageh, imagebpp * 8);
 #endif
@@ -168,7 +172,17 @@ main(int argc, char *argv[])
                errx(EXIT_FAILURE, "XCreateImage failed");
        }
        XInitImage(image);
-       image->byte_order = byte_order;
+
+       /*
+        * Set the image byte order.  Since the above code has converted it
+        * into host endian this will need to be communicated to the display
+        * server so it can re-swizzle if needed.
+        */
+#if _BYTE_ORDER == _BIG_ENDIAN
+       image->byte_order = MSBFirst;
+#else
+       image->byte_order = LSBFirst;
+#endif

        /* Create a graphics context for our new pixmap */
        gc = XCreateGC(display, window, 0, NULL);

>Audit-Trail:
From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Sat, 31 Jan 2026 14:30:54 +0300

 FWIW, xsetwallpaper photo.jpg DTRT for me when I run it on a
 (big-endian) macppc (running 10-stable) host with the display to Xnest
 on a (little-endian) linux/amd64.

 -uwe

From: Adrian Chadd <adrian@freebsd.org>
To: gnats-bugs@netbsd.org
Cc: xsrc-manager@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Sat, 31 Jan 2026 08:51:38 -0800

 On Sat, 31 Jan 2026 at 03:35, Valery Ushakov via gnats
 <gnats-admin@netbsd.org> wrote:
 >
 > The following reply was made to PR xsrc/59952; it has been noted by GNATS.
 >
 > From: Valery Ushakov <uwe@stderr.spb.ru>
 > To: gnats-bugs@netbsd.org
 > Cc:
 > Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
 > Date: Sat, 31 Jan 2026 14:30:54 +0300
 >
 >  FWIW, xsetwallpaper photo.jpg DTRT for me when I run it on a
 >  (big-endian) macppc (running 10-stable) host with the display to Xnest
 >  on a (little-endian) linux/amd64.

 Would you mind adding some printf debugging to see what the image endianness is?

 My setup (sgimips/be xserver, amd64/le client) prints that the default
 byte_order for the
 root window is MSB (big endian), which won't match the little-endian image data.

 My diff looks like this (it's from a bigger diff set, but you should
 be able to copy/paste
 the lines minus the '+' at the beginning into the right place,
 recompile and test.)

 ===
         XInitImage(image);

 +       printf("byte order: %d (msb=%d lsb=%d)\n",
 +           byte_order, MSBFirst, LSBFirst);
 ===


 -adrian

 >  -uwe
 >

From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: "Jared D. McNeill" <jmcneill@netbsd.org>
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Sun, 1 Feb 2026 02:10:37 +0300

 Ok, I see.  The colors where wrong and disabling the big-endian ifdef
 makes the image come out right.  But in my defense - your report never
 really explained properly what you observe and "corrupted" can mean a
 lot of different things.

 Jared is now having fun with Wii (powerpc), should be easy for him to
 reproduce locally :)

 -uwe

From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Wed, 4 Feb 2026 03:41:19 +0300

 I'm not sure if the server is guaranteed to handle byte order other
 than the ImageByteOrder it announces on the server side.  But from a
 very quick look it seems that xlib will take care of bswapping the
 image as necessary.  But instead of relying on someone doing that for
 us it might be easier to just provide the image in the right odrder,
 as we need to shuffle components anyway.

 Something like that?  Only very minimally tested.

 --- xsetwallpaper.c.~1.4.~	2026-02-03 00:03:28.073085100 +0300
 +++ xsetwallpaper.c	2026-02-04 03:28:37.929559236 +0300
 @@ -95,22 +95,6 @@ main(int argc, char *argv[])
  	data = stbi_load(argv[0], &imagew, &imageh, &imagebpp, 4);
  	if (data == NULL)
  		errx(EXIT_FAILURE, "failed to load %s", argv[0]);
 -
 -	/* swap red and blue */
 -	for (i = 0; i < imagew * imageh * 4; i += 4) {
 -		uint8_t p;
 -		p = data[i + 0];
 -		data[i + 0] = data[i + 2];
 -		data[i + 2] = p;
 -	}
 -
 -#if _BYTE_ORDER == _BIG_ENDIAN
 -	for (i = 0; i < imagew * imageh * 4; i += 4) {
 -		uint32_t *p = (uint32_t *)&data[i];
 -		*p = bswap32(*p);
 -	}
 -#endif
 -
  #ifdef DEBUG
  	printf("%s: %dx%d %dbpp\n", argv[0], imagew, imageh, imagebpp * 8);
  #endif
 @@ -126,6 +110,30 @@ main(int argc, char *argv[])
  	colormap = DefaultColormap(display, 0);
  	byte_order = ImageByteOrder(display);

 +	/*
 +	 * stbi loads 4-component image as red, green, blue, alpha -
 +	 * i.e. little-endian ABGR.  We need to provide it to the
 +	 * server in ARGB in ImageByteOrder(3).
 +	 */
 +	enum { R, G, B, A };
 +
 +#if _BYTE_ORDER == _BIG_ENDIAN
 +#	define host_byte_order MSBFirst
 +#else
 +#	define host_byte_order LSBFirst
 +#endif
 +	uint32_t *data32 = (uint32_t *)data;
 +	for (i = 0; i < imagew * imageh; ++i) {
 +		uint32_t pixel =
 +			  data[i*4 + A] << 24
 +			| data[i*4 + R] << 16
 +			| data[i*4 + G] <<  8
 +			| data[i*4 + B];
 +		if (byte_order != host_byte_order)
 +			pixel = bswap32(pixel);
 +		data32[i] = pixel;
 +	}
 +
  	/* get root window geometry */
  	if (!XGetGeometry(display, XDefaultRootWindow(display), &window,
  	    &root_x, &root_y, &root_width, &root_height,

 -uwe

From: Adrian Chadd <adrian@freebsd.org>
To: gnats-bugs@netbsd.org
Cc: xsrc-manager@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Tue, 3 Feb 2026 17:03:45 -0800

 Well, my next diff is handling servers that aren't ARGB. :-P

 I'm tempted to lean in here and not bswap at all but let x11 do it. I
 believe that's what the API is meant to encourage.


 -adrian

From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Wed, 4 Feb 2026 06:57:11 -0000 (UTC)

 gnats-admin@NetBSD.org ("Adrian Chadd via gnats") writes:

 > Well, my next diff is handling servers that aren't ARGB. :-P
 > 
 > I'm tempted to lean in here and not bswap at all but let x11 do it. I
 > believe that's what the API is meant to encourage.


 XCreateImage() gets you an XImage suited for the display and visual.
 You then create the pixel data in the appropriate format and
 XPutImage() transfers it to the server.

 XInitImage() lets you create an XImage yourself for the format you
 specify. If the characteristics of the image (for example, byte_order
 and bitmap_unit) differ from what the server requires, XPutImage()
 makes the necessary conversions.

 XImage contains pointers to pixel manipulation functions (that
 XInitImage will initialize). So you should not modify the XImage
 structure yourself after it is initialized or created by some
 Xlib function.

 The pixel depth is nothing that could be converted automatically,
 operations with different depths always fail with a BadMatch.

 You can render a XYBitmap to a deeper display because the XYBitmap
 is seen as pixels in background (0-bits) and foreground (1-bits)
 color. So there is no depth conversion taking place between pixel
 values.

 Saying that, automatic conversions was never popular. Any conversion
 is slow, especially when done with single pixel operations. The code
 I've seen that relied on this was usually handling small pre-rendered
 images in a user interface (like button imagery). Everything else would
 convert the data once when loading or generating an image and not
 every time when it gets rendered for refreshing a window. Something
 like xsetwallpaper probably doesn't care, as rendering is done only once.


From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Wed, 4 Feb 2026 13:28:04 +0300

 On Wed, Feb 04, 2026 at 01:05:01 +0000, Adrian Chadd via gnats wrote:

 >  Well, my next diff is handling servers that aren't ARGB. :-P

 I thought about that too, but that's not a rabbit hole I currently
 have enough time for.


 >  I'm tempted to lean in here and not bswap at all but let x11 do it.
 >  I believe that's what the API is meant to encourage.

 I'd rather we handle it explicitly in the xsetwallpaper code.  We
 almost always need to shuffle the bytes anyway, so it's less cognitive
 load on the reader to shuffle it to the order the server wants, than
 to shuffle them into some other order and then let some other code
 shuffle them some more (doing the work twice, not that xsetwallpaper
 is perforamce critical code, as Michael said).

 Could you kindly make your extended non-argb patch to go down that
 direction?

 PS: From a private chat with Jared:

 | feel free to commit the fix


 -uwe

From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Wed, 4 Feb 2026 15:07:51 +0300

 See also: xsrc/58580

 -uwe

From: Adrian Chadd <adrian@freebsd.org>
To: gnats-bugs@netbsd.org
Cc: xsrc-manager@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Wed, 4 Feb 2026 07:14:47 -0800

 commit what works, heh. I'll go rebase what i'm doing on top of it!

 Thanks!


 -adrian

From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Thu, 5 Feb 2026 01:15:50 +0300

 Can you give it some testing for the client/server permutations you
 have?  Nearly all of my netbsd machines are headless.  My macppc mini
 is in a closet w/out a monitor and I no longer have anything 13w3 to
 hook up to my ultra.

 TIA

 -uwe

From: Adrian Chadd <adrian@freebsd.org>
To: gnats-bugs@netbsd.org
Cc: xsrc-manager@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Thu, 5 Feb 2026 17:26:35 -0800

 i tested both be/le client/server combo, and be server/client.


 -a

From: "Valery Ushakov" <uwe@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/59952 CVS commit: xsrc/local/programs/xsetwallpaper
Date: Wed, 11 Feb 2026 00:09:12 +0000

 Module Name:	xsrc
 Committed By:	uwe
 Date:		Wed Feb 11 00:09:12 UTC 2026

 Modified Files:
 	xsrc/local/programs/xsetwallpaper: xsetwallpaper.c

 Log Message:
 xsetwallpaper: create the image in the server's byte order

 PR xsrc/59952


 To generate a diff of this commit:
 cvs rdiff -u -r1.4 -r1.5 xsrc/local/programs/xsetwallpaper/xsetwallpaper.c

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

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.