untrusted comment: verify with openbsd-71-base.pub
RWR2eHwZTOEiTSrFWoAQfoBkFN6XK2hhNpYcSsoso33AmX6CK8cKeM3m6klTWY/pB9p7T38JSJfUeY880ZerOjpts66++5N9Wwg=

OpenBSD 7.1 errata 019, January 17, 2023

Input validation issues and path validation issues in libXpm can lead
to infinite loops, memory corruption or arbitrary command execution.
CVE-2022-46285, CVE-2022-44617 and CVE-2022-4883

Apply by doing:
   signify -Vep /etc/signify/openbsd-71-base.pub -x 019_libxpm.patch.sig \
       -m - | (cd /usr/xenocara && patch -p0)

And then compile and rebuild libXpm
   cd /usr/xenocara/lib/libXpm
   make -f Makefile.bsd-wrapper obj
   make -f Makefile.bsd-wrapper build

Index: lib/libXpm/Makefile.in
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/Makefile.in,v
diff -u -p -u -r1.10 Makefile.in
--- lib/libXpm/Makefile.in      4 Jan 2020 18:00:46 -0000       1.10
+++ lib/libXpm/Makefile.in      15 Jan 2023 18:03:40 -0000
@@ -268,6 +268,10 @@ VERSION = @VERSION@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
XPM_CFLAGS = @XPM_CFLAGS@
XPM_LIBS = @XPM_LIBS@
+XPM_PATH_COMPRESS = @XPM_PATH_COMPRESS@
+XPM_PATH_GUNZIP = @XPM_PATH_GUNZIP@
+XPM_PATH_GZIP = @XPM_PATH_GZIP@
+XPM_PATH_UNCOMPRESS = @XPM_PATH_UNCOMPRESS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
Index: lib/libXpm/config.h.in
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/config.h.in,v
diff -u -p -u -r1.5 config.h.in
--- lib/libXpm/config.h.in      28 Sep 2013 17:40:33 -0000      1.5
+++ lib/libXpm/config.h.in      15 Jan 2023 18:03:40 -0000
@@ -1,5 +1,11 @@
/* config.h.in.  Generated from configure.ac by autoheader.  */

+/* Define to 1 if you have the `closefrom' function. */
+#undef HAVE_CLOSEFROM
+
+/* Define to 1 if you have the `close_range' function. */
+#undef HAVE_CLOSE_RANGE
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H

@@ -73,9 +79,6 @@
/* Patch version of this package */
#undef PACKAGE_VERSION_PATCHLEVEL

-/* Define to 1 to automatically look for files with .Z & .gz extensions */
-#undef STAT_ZFILE
-
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS

@@ -84,3 +87,15 @@

/* Version number of package */
#undef VERSION
+
+/* Path to compress */
+#undef XPM_PATH_COMPRESS
+
+/* Path to gunzip */
+#undef XPM_PATH_GUNZIP
+
+/* Path to gzip */
+#undef XPM_PATH_GZIP
+
+/* Path to uncompress */
+#undef XPM_PATH_UNCOMPRESS
Index: lib/libXpm/configure
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/configure,v
diff -u -p -u -r1.16 configure
--- lib/libXpm/configure        4 Jan 2020 18:00:46 -0000       1.16
+++ lib/libXpm/configure        15 Jan 2023 18:03:40 -0000
@@ -637,6 +637,10 @@ ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
+XPM_PATH_GUNZIP
+XPM_PATH_GZIP
+XPM_PATH_UNCOMPRESS
+XPM_PATH_COMPRESS
USE_GETTEXT_FALSE
USE_GETTEXT_TRUE
LOCALEDIR
@@ -799,7 +803,6 @@ enable_selective_werror
enable_strict_compilation
enable_silent_rules
with_localedir
-enable_stat_zfile
'
      ac_precious_vars='build_alias
host_alias
@@ -1455,8 +1458,6 @@ Optional Features:
                          errors (default: disabled)
  --enable-silent-rules   less verbose build output (undo: "make V=1")
  --disable-silent-rules  verbose build output (undo: "make V=0")
-  --enable-stat-zfile     Search for files with .Z & .gz extensions
-                          automatically [default=yes]

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -17878,30 +17879,227 @@ else
fi


-# Optional feature: When ___.xpm is requested, also look for ___.xpm.Z & .gz
-# Replaces ZFILEDEF = -DSTAT_ZFILE in old Imakefile
-# Check whether --enable-stat-zfile was given.
-if test "${enable_stat_zfile+set}" = set; then :
-  enableval=$enable_stat_zfile; STAT_ZFILE=$enableval
+
+case $host_os in
+        *mingw*)
+
+$as_echo "#define NO_ZPIPE 1" >>confdefs.h
+
+        ;;
+        *)
+
+# Extract the first word of "compress", so it can be a program name with args.
+set dummy compress; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_XPM_PATH_COMPRESS+:} false; then :
+  $as_echo_n "(cached) " >&6
else
-  STAT_ZFILE=yes
+  case $XPM_PATH_COMPRESS in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_XPM_PATH_COMPRESS="$XPM_PATH_COMPRESS" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_XPM_PATH_COMPRESS="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
fi
+XPM_PATH_COMPRESS=$ac_cv_path_XPM_PATH_COMPRESS
+if test -n "$XPM_PATH_COMPRESS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XPM_PATH_COMPRESS" >&5
+$as_echo "$XPM_PATH_COMPRESS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "x$XPM_PATH_COMPRESS" = "x"; then :
+  as_fn_error $? "compress not found, set XPM_PATH_COMPRESS or use --disable-stat-zfile" "$LINENO" 5
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define XPM_PATH_COMPRESS "$XPM_PATH_COMPRESS"
+_ACEOF

-if test x$STAT_ZFILE = xyes ; then

-$as_echo "#define STAT_ZFILE 1" >>confdefs.h

+# Extract the first word of "uncompress", so it can be a program name with args.
+set dummy uncompress; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_XPM_PATH_UNCOMPRESS+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $XPM_PATH_UNCOMPRESS in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_XPM_PATH_UNCOMPRESS="$XPM_PATH_UNCOMPRESS" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_XPM_PATH_UNCOMPRESS="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+XPM_PATH_UNCOMPRESS=$ac_cv_path_XPM_PATH_UNCOMPRESS
+if test -n "$XPM_PATH_UNCOMPRESS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XPM_PATH_UNCOMPRESS" >&5
+$as_echo "$XPM_PATH_UNCOMPRESS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi


-case $host_os in
-       *mingw*)
+if test "x$XPM_PATH_UNCOMPRESS" = "x"; then :
+  as_fn_error $? "uncompress not found, set XPM_PATH_UNCOMPRESS or use --disable-stat-zfile" "$LINENO" 5
+fi

-$as_echo "#define NO_ZPIPE 1" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define XPM_PATH_UNCOMPRESS "$XPM_PATH_UNCOMPRESS"
+_ACEOF

-       ;;
-       *)
-       ;;
+
+
+# Extract the first word of "gzip", so it can be a program name with args.
+set dummy gzip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_XPM_PATH_GZIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $XPM_PATH_GZIP in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_XPM_PATH_GZIP="$XPM_PATH_GZIP" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_XPM_PATH_GZIP="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+XPM_PATH_GZIP=$ac_cv_path_XPM_PATH_GZIP
+if test -n "$XPM_PATH_GZIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XPM_PATH_GZIP" >&5
+$as_echo "$XPM_PATH_GZIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "x$XPM_PATH_GZIP" = "x"; then :
+  as_fn_error $? "gzip not found, set XPM_PATH_GZIP or use --disable-stat-zfile" "$LINENO" 5
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define XPM_PATH_GZIP "$XPM_PATH_GZIP"
+_ACEOF
+
+
+
+# Extract the first word of "gunzip", so it can be a program name with args.
+set dummy gunzip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_XPM_PATH_GUNZIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $XPM_PATH_GUNZIP in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_XPM_PATH_GUNZIP="$XPM_PATH_GUNZIP" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_XPM_PATH_GUNZIP="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+XPM_PATH_GUNZIP=$ac_cv_path_XPM_PATH_GUNZIP
+if test -n "$XPM_PATH_GUNZIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XPM_PATH_GUNZIP" >&5
+$as_echo "$XPM_PATH_GUNZIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "x$XPM_PATH_GUNZIP" = "x"; then :
+  as_fn_error $? "gunzip not found, set XPM_PATH_GUNZIP or use --disable-stat-zfile" "$LINENO" 5
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define XPM_PATH_GUNZIP "$XPM_PATH_GUNZIP"
+_ACEOF
+
+
+                for ac_func in closefrom close_range
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+done
+
+        ;;
esac

ac_config_files="$ac_config_files Makefile doc/Makefile include/Makefile man/Makefile src/Makefile sxpm/Makefile cxpm/Makefile xpm.pc"
Index: lib/libXpm/configure.ac
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/configure.ac,v
diff -u -p -u -r1.7 configure.ac
--- lib/libXpm/configure.ac     4 Jan 2020 18:00:46 -0000       1.7
+++ lib/libXpm/configure.ac     15 Jan 2023 18:03:40 -0000
@@ -49,23 +49,25 @@ if test "x$USE_GETTEXT" = "xyes" ; then
fi
AM_CONDITIONAL(USE_GETTEXT, test "x$USE_GETTEXT" = "xyes")

-# Optional feature: When ___.xpm is requested, also look for ___.xpm.Z & .gz
-# Replaces ZFILEDEF = -DSTAT_ZFILE in old Imakefile
-AC_ARG_ENABLE(stat-zfile,
-       AS_HELP_STRING([--enable-stat-zfile],
-                       [Search for files with .Z & .gz extensions automatically @<:@default=yes@:>@]),
-              [STAT_ZFILE=$enableval], [STAT_ZFILE=yes])
-if test x$STAT_ZFILE = xyes ; then
-       AC_DEFINE(STAT_ZFILE, 1, [Define to 1 to automatically look for files with .Z & .gz extensions])
-fi
-
+dnl Helper macro to find absolute path to program and add a #define for it
+AC_DEFUN([XPM_PATH_PROG],[
+AC_PATH_PROG([$1], [$2], [])
+AS_IF([test "x$$1" = "x"],
+      [AC_MSG_ERROR([$2 not found, set $1 or use --disable-stat-zfile])])
+AC_DEFINE_UNQUOTED([$1], ["$$1"], [Path to $2])
+]) dnl End of AC_DEFUN([XPM_PATH_PROG]...

case $host_os in
-       *mingw*)
+        *mingw*)
                AC_DEFINE(NO_ZPIPE, 1, [Define to 1 to disable decompression via pipes])
-       ;;
-       *)
-       ;;
+        ;;
+        *)
+                XPM_PATH_PROG([XPM_PATH_COMPRESS], [compress])
+                XPM_PATH_PROG([XPM_PATH_UNCOMPRESS], [uncompress])
+                XPM_PATH_PROG([XPM_PATH_GZIP], [gzip])
+                XPM_PATH_PROG([XPM_PATH_GUNZIP], [gunzip])
+                AC_CHECK_FUNCS([closefrom close_range], [break])
+        ;;
esac

AC_CONFIG_FILES([Makefile
Index: lib/libXpm/cxpm/Makefile.in
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/cxpm/Makefile.in,v
diff -u -p -u -r1.8 Makefile.in
--- lib/libXpm/cxpm/Makefile.in 11 Oct 2016 22:15:33 -0000      1.8
+++ lib/libXpm/cxpm/Makefile.in 15 Jan 2023 18:03:40 -0000
@@ -210,6 +210,10 @@ VERSION = @VERSION@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
XPM_CFLAGS = @XPM_CFLAGS@
XPM_LIBS = @XPM_LIBS@
+XPM_PATH_COMPRESS = @XPM_PATH_COMPRESS@
+XPM_PATH_GUNZIP = @XPM_PATH_GUNZIP@
+XPM_PATH_GZIP = @XPM_PATH_GZIP@
+XPM_PATH_UNCOMPRESS = @XPM_PATH_UNCOMPRESS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
Index: lib/libXpm/doc/Makefile.in
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/doc/Makefile.in,v
diff -u -p -u -r1.4 Makefile.in
--- lib/libXpm/doc/Makefile.in  11 Oct 2016 22:15:33 -0000      1.4
+++ lib/libXpm/doc/Makefile.in  15 Jan 2023 18:03:40 -0000
@@ -172,6 +172,10 @@ VERSION = @VERSION@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
XPM_CFLAGS = @XPM_CFLAGS@
XPM_LIBS = @XPM_LIBS@
+XPM_PATH_COMPRESS = @XPM_PATH_COMPRESS@
+XPM_PATH_GUNZIP = @XPM_PATH_GUNZIP@
+XPM_PATH_GZIP = @XPM_PATH_GZIP@
+XPM_PATH_UNCOMPRESS = @XPM_PATH_UNCOMPRESS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
Index: lib/libXpm/include/Makefile.in
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/include/Makefile.in,v
diff -u -p -u -r1.5 Makefile.in
--- lib/libXpm/include/Makefile.in      11 Oct 2016 22:15:33 -0000      1.5
+++ lib/libXpm/include/Makefile.in      15 Jan 2023 18:03:40 -0000
@@ -205,6 +205,10 @@ VERSION = @VERSION@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
XPM_CFLAGS = @XPM_CFLAGS@
XPM_LIBS = @XPM_LIBS@
+XPM_PATH_COMPRESS = @XPM_PATH_COMPRESS@
+XPM_PATH_GUNZIP = @XPM_PATH_GUNZIP@
+XPM_PATH_GZIP = @XPM_PATH_GZIP@
+XPM_PATH_UNCOMPRESS = @XPM_PATH_UNCOMPRESS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
Index: lib/libXpm/man/Makefile.in
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/man/Makefile.in,v
diff -u -p -u -r1.3 Makefile.in
--- lib/libXpm/man/Makefile.in  11 Oct 2016 22:15:33 -0000      1.3
+++ lib/libXpm/man/Makefile.in  15 Jan 2023 18:03:41 -0000
@@ -225,6 +225,10 @@ VERSION = @VERSION@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
XPM_CFLAGS = @XPM_CFLAGS@
XPM_LIBS = @XPM_LIBS@
+XPM_PATH_COMPRESS = @XPM_PATH_COMPRESS@
+XPM_PATH_GUNZIP = @XPM_PATH_GUNZIP@
+XPM_PATH_GZIP = @XPM_PATH_GZIP@
+XPM_PATH_UNCOMPRESS = @XPM_PATH_UNCOMPRESS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
Index: lib/libXpm/src/Makefile.in
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/Makefile.in,v
diff -u -p -u -r1.8 Makefile.in
--- lib/libXpm/src/Makefile.in  11 Oct 2016 22:15:33 -0000      1.8
+++ lib/libXpm/src/Makefile.in  15 Jan 2023 18:03:41 -0000
@@ -245,6 +245,10 @@ VERSION = @VERSION@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
XPM_CFLAGS = @XPM_CFLAGS@
XPM_LIBS = @XPM_LIBS@
+XPM_PATH_COMPRESS = @XPM_PATH_COMPRESS@
+XPM_PATH_GUNZIP = @XPM_PATH_GUNZIP@
+XPM_PATH_GZIP = @XPM_PATH_GZIP@
+XPM_PATH_UNCOMPRESS = @XPM_PATH_UNCOMPRESS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
Index: lib/libXpm/src/RdFToI.c
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/RdFToI.c,v
diff -u -p -u -r1.4 RdFToI.c
--- lib/libXpm/src/RdFToI.c     28 Sep 2013 17:40:35 -0000      1.4
+++ lib/libXpm/src/RdFToI.c     15 Jan 2023 18:03:41 -0000
@@ -43,6 +43,7 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <unistd.h>
#else
#ifdef FOR_MSW
#include <fcntl.h>
@@ -161,7 +162,17 @@ xpmPipeThrough(
           goto err;
       if ( 0 == pid )
       {
-           execlp(cmd, cmd, arg1, (char *)NULL);
+#ifdef HAVE_CLOSEFROM
+           closefrom(3);
+#elif defined(HAVE_CLOSE_RANGE)
+# ifdef CLOSE_RANGE_UNSHARE
+#  define close_range_flags CLOSE_RANGE_UNSHARE
+# else
+#  define close_range_flags 0
+#endif
+           close_range(3, ~0U, close_range_flags);
+#endif
+           execl(cmd, cmd, arg1, (char *)NULL);
           perror(cmd);
           goto err;
       }
@@ -235,12 +246,12 @@ OpenReadFile(
       if ( ext && !strcmp(ext, ".Z") )
       {
           mdata->type = XPMPIPE;
-           mdata->stream.file = xpmPipeThrough(fd, "uncompress", "-c", "r");
+           mdata->stream.file = xpmPipeThrough(fd, XPM_PATH_UNCOMPRESS, "-c", "r");
       }
       else if ( ext && !strcmp(ext, ".gz") )
       {
           mdata->type = XPMPIPE;
-           mdata->stream.file = xpmPipeThrough(fd, "gunzip", "-qc", "r");
+           mdata->stream.file = xpmPipeThrough(fd, XPM_PATH_GUNZIP, "-qc", "r");
       }
       else
#endif /* z-files */
Index: lib/libXpm/src/WrFFrI.c
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/WrFFrI.c,v
diff -u -p -u -r1.6 WrFFrI.c
--- lib/libXpm/src/WrFFrI.c     4 Jan 2020 18:00:46 -0000       1.6
+++ lib/libXpm/src/WrFFrI.c     15 Jan 2023 18:03:41 -0000
@@ -342,10 +342,10 @@ OpenWriteFile(
#ifndef NO_ZPIPE
       len = strlen(filename);
       if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
-           mdata->stream.file = xpmPipeThrough(fd, "compress", NULL, "w");
+           mdata->stream.file = xpmPipeThrough(fd, XPM_PATH_COMPRESS, NULL, "w");
           mdata->type = XPMPIPE;
       } else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
-           mdata->stream.file = xpmPipeThrough(fd, "gzip", "-q", "w");
+           mdata->stream.file = xpmPipeThrough(fd, XPM_PATH_GZIP, "-q", "w");
           mdata->type = XPMPIPE;
       } else
#endif
Index: lib/libXpm/src/create.c
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/create.c,v
diff -u -p -u -r1.5 create.c
--- lib/libXpm/src/create.c     16 Dec 2016 07:28:34 -0000      1.5
+++ lib/libXpm/src/create.c     15 Jan 2023 18:03:41 -0000
@@ -994,6 +994,7 @@ CreateXImage(
#if !defined(FOR_MSW) && !defined(AMIGA)
    if (height != 0 && (*image_return)->bytes_per_line >= INT_MAX / height) {
       XDestroyImage(*image_return);
+       *image_return = NULL;
       return XpmNoMemory;
    }
    /* now that bytes_per_line must have been set properly alloc data */
Index: lib/libXpm/src/data.c
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/data.c,v
diff -u -p -u -r1.4 data.c
--- lib/libXpm/src/data.c       10 Mar 2012 14:30:33 -0000      1.4
+++ lib/libXpm/src/data.c       15 Jan 2023 18:03:41 -0000
@@ -174,6 +174,10 @@ ParseComment(xpmData *data)
               notend = 0;
               Ungetc(data, *s, file);
           }
+           else if (c == EOF) {
+               /* hit end of file before the end of the comment */
+               return XpmFileInvalid;
+           }
       }
       return 0;
    }
@@ -191,19 +195,23 @@ xpmNextString(xpmData *data)
       register char c;

       /* get to the end of the current string */
-       if (data->Eos)
-           while ((c = *data->cptr++) && c != data->Eos);
+       if (data->Eos) {
+           while ((c = *data->cptr++) && c != data->Eos && c != '\0');
+
+           if (c == '\0')
+               return XpmFileInvalid;
+       }

       /*
        * then get to the beginning of the next string looking for possible
        * comment
        */
       if (data->Bos) {
-           while ((c = *data->cptr++) && c != data->Bos)
+           while ((c = *data->cptr++) && c != data->Bos && c != '\0')
               if (data->Bcmt && c == data->Bcmt[0])
                   ParseComment(data);
       } else if (data->Bcmt) {        /* XPM2 natural */
-           while ((c = *data->cptr++) == data->Bcmt[0])
+           while (((c = *data->cptr++) == data->Bcmt[0]) && c != '\0')
               ParseComment(data);
           data->cptr--;
       }
@@ -212,9 +220,13 @@ xpmNextString(xpmData *data)
       FILE *file = data->stream.file;

       /* get to the end of the current string */
-       if (data->Eos)
+       if (data->Eos) {
           while ((c = Getc(data, file)) != data->Eos && c != EOF);

+           if (c == EOF)
+               return XpmFileInvalid;
+       }
+
       /*
        * then get to the beginning of the next string looking for possible
        * comment
@@ -230,7 +242,7 @@ xpmNextString(xpmData *data)
           Ungetc(data, c, file);
       }
    }
-    return 0;
+    return XpmSuccess;
}


Index: lib/libXpm/src/parse.c
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/parse.c,v
diff -u -p -u -r1.6 parse.c
--- lib/libXpm/src/parse.c      4 Jan 2020 18:00:46 -0000       1.6
+++ lib/libXpm/src/parse.c      15 Jan 2023 18:03:41 -0000
@@ -427,6 +427,13 @@ ParsePixels(
{
    unsigned int *iptr, *iptr2 = NULL; /* found by Egbert Eich */
    unsigned int a, x, y;
+    int ErrorStatus;
+
+    if ((width == 0) && (height != 0))
+       return (XpmFileInvalid);
+
+    if ((height == 0) && (width != 0))
+       return (XpmFileInvalid);

    if ((height > 0 && width >= UINT_MAX / height) ||
       width * height >= UINT_MAX / sizeof(unsigned int))
@@ -464,7 +471,11 @@ ParsePixels(
               colidx[(unsigned char)colorTable[a].string[0]] = a + 1;

           for (y = 0; y < height; y++) {
-               xpmNextString(data);
+               ErrorStatus = xpmNextString(data);
+               if (ErrorStatus != XpmSuccess) {
+                   XpmFree(iptr2);
+                   return (ErrorStatus);
+               }
               for (x = 0; x < width; x++, iptr++) {
                   int c = xpmGetC(data);

@@ -511,7 +522,11 @@ do \
           }

           for (y = 0; y < height; y++) {
-               xpmNextString(data);
+               ErrorStatus = xpmNextString(data);
+               if (ErrorStatus != XpmSuccess) {
+                   XpmFree(iptr2);
+                   return (ErrorStatus);
+               }
               for (x = 0; x < width; x++, iptr++) {
                   int cc1 = xpmGetC(data);
                   if (cc1 > 0 && cc1 < 256) {
@@ -551,7 +566,11 @@ do \
               xpmHashAtom *slot;

               for (y = 0; y < height; y++) {
-                   xpmNextString(data);
+                   ErrorStatus = xpmNextString(data);
+                   if (ErrorStatus != XpmSuccess) {
+                       XpmFree(iptr2);
+                       return (ErrorStatus);
+                   }
                   for (x = 0; x < width; x++, iptr++) {
                       for (a = 0, s = buf; a < cpp; a++, s++) {
                           int c = xpmGetC(data);
@@ -571,7 +590,11 @@ do \
               }
           } else {
               for (y = 0; y < height; y++) {
-                   xpmNextString(data);
+                   ErrorStatus = xpmNextString(data);
+                   if (ErrorStatus != XpmSuccess) {
+                       XpmFree(iptr2);
+                       return (ErrorStatus);
+                   }
                   for (x = 0; x < width; x++, iptr++) {
                       for (a = 0, s = buf; a < cpp; a++, s++) {
                           int c = xpmGetC(data);
Index: lib/libXpm/sxpm/Makefile.in
===================================================================
RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/sxpm/Makefile.in,v
diff -u -p -u -r1.8 Makefile.in
--- lib/libXpm/sxpm/Makefile.in 11 Oct 2016 22:15:33 -0000      1.8
+++ lib/libXpm/sxpm/Makefile.in 15 Jan 2023 18:03:41 -0000
@@ -214,6 +214,10 @@ VERSION = @VERSION@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
XPM_CFLAGS = @XPM_CFLAGS@
XPM_LIBS = @XPM_LIBS@
+XPM_PATH_COMPRESS = @XPM_PATH_COMPRESS@
+XPM_PATH_GUNZIP = @XPM_PATH_GUNZIP@
+XPM_PATH_GZIP = @XPM_PATH_GZIP@
+XPM_PATH_UNCOMPRESS = @XPM_PATH_UNCOMPRESS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@