#! /bin/sh -e ## 19_fix_root_c_resource_leak.dpatch ## ## DP: Fix leaking xresources when using onroot option. See #325689. ## DP: Patch by Alex Perry, reformatted by Tim Connors if [ $# -ne 1 ]; then echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1 fi case "$1" in -patch) patch -f --no-backup-if-mismatch -p1 < $0;; -unpatch) patch -f --no-backup-if-mismatch -R -p1 < $0;; *) echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1;; esac exit 0 @DPATCH@ diff -urNad xloadimage-4.1~/root.c xloadimage-4.1/root.c --- xloadimage-4.1~/root.c 2008-11-22 19:52:01.000000000 +0100 +++ xloadimage-4.1/root.c 2008-11-22 19:52:02.000000000 +0100 @@ -16,24 +16,6 @@ #define RETAIN_PROP_NAME "_XSETROOT_ID" -void updateProperty(dpy, w, name, type, format, data, nelem) - Display *dpy; - Window w; - char *name; - Atom type; - int format; - int data; - int nelem; -{ - /* intern the property name */ - Atom atom = XInternAtom(dpy, name, 0); - - /* create or replace the property */ - XChangeProperty(dpy, w, atom, type, format, PropModeReplace, - (unsigned char *)&data, nelem); -} - - /* Sets the close-down mode of the client to 'RetainPermanent' * so all client resources will be preserved after the client * exits. Puts a property on the default root window containing @@ -47,9 +29,15 @@ { /* create dummy resource */ Pixmap pm= XCreatePixmap(dpy, w, 1, 1, 1); + unsigned char *data = (unsigned char *) ± - /* create/replace the property */ - updateProperty(dpy, w, RETAIN_PROP_NAME, XA_PIXMAP, 32, (int)pm, 1); + /* intern the property name */ + char *name = RETAIN_PROP_NAME; + Atom atom = XInternAtom(dpy, name, 0); + + /* create or replace the property */ + XChangeProperty(dpy, w, atom, XA_PIXMAP, 32, PropModeReplace, + data, sizeof(Pixmap)/4); /* retain all client resources until explicitly killed */ XSetCloseDownMode(dpy, RetainPermanent); @@ -61,36 +49,64 @@ */ static void -freePrevious(dpy, w) +freePrevious(dpy, w, verbose) Display *dpy; Window w; + unsigned int verbose; { - Pixmap *pm; - Atom actual_type; /* NOTUSED */ + Pixmap *pm; + unsigned char *charpm; + Atom actual_type; int format; - int nitems; - int bytes_after; + unsigned long nitems; + unsigned long bytes_after; + int returncode; /* intern the property name */ Atom atom = XInternAtom(dpy, RETAIN_PROP_NAME, 0); /* look for existing resource allocation */ - if ((XGetWindowProperty(dpy, w, atom, 0, 1, 1/*delete*/, - AnyPropertyType, &actual_type, &format, (unsigned long *)&nitems, - (unsigned long *)&bytes_after, (unsigned char **)&pm) == Success) && - nitems == 1) { - if ((actual_type == XA_PIXMAP) && (format == 32) && - (nitems == 1) && (bytes_after == 0)) { - /* blast it away */ - XKillClient(dpy, (XID) *pm); - XFree((char *)pm); - } - else if (actual_type != None) { - fprintf(stderr, - "%s: warning: invalid format encountered for property %s\n", - RETAIN_PROP_NAME, "xloadimage"); - } + nitems = sizeof(Pixmap)/4; + returncode = XGetWindowProperty(dpy, w, atom, + 0, nitems, 1/*delete*/, + XA_PIXMAP, &actual_type, + &format, &nitems, + &bytes_after, &charpm); + if (returncode != Success) { + if (verbose) + fprintf(stderr, "failed to look for %s with return code %i.\n", + RETAIN_PROP_NAME, returncode); + return; + } + + /* Check if the property was found */ + if (actual_type == None) { + if (verbose) + fprintf(stderr, "didn't find evidence of prior run.\n"); + return; + } + + /* Make sure the dummy value is still present */ + if (actual_type != XA_PIXMAP) { + if (verbose) + fprintf(stderr, "found wrong data type - skipped.\n"); + return; + } + + /* Check size, in case we're a different architecture */ + if ((nitems != sizeof(Pixmap)/4) || + (format != 32) || + (bytes_after != 0)) { + if (verbose) + fprintf(stderr, "saw wrong %li / word size %i / architecture %li.\n", + bytes_after, format, nitems); + return; } + + /* blast it away */ + pm = (Pixmap*) charpm; + XKillClient(dpy, (XID) *pm); + XFree(charpm); } #if FIND_DEC_ROOTWINDOW @@ -185,20 +201,21 @@ for(i = 0; i < numChildren; i++) { Atom actual_type; int actual_format; - long nitems, bytesafter; - Window *newRoot = NULL; - - if (XGetWindowProperty (disp, children[i], __SWM_VROOT,0,1, - False, XA_WINDOW, &actual_type, &actual_format, - (unsigned long *)&nitems, (unsigned long *)&bytesafter, - (unsigned char **) &newRoot) == - Success && newRoot) { - root = *newRoot; + unsigned long nitems, bytesafter; + unsigned char *newRoot = 0; + + if ((XGetWindowProperty (disp, children[i], __SWM_VROOT,0,1, + False, XA_WINDOW, + &actual_type, &actual_format, + &nitems, &bytesafter, &newRoot) + == Success) && + newRoot) { + root = *((Window*) newRoot); break; } } } - freePrevious(disp, root); + freePrevious(disp, root, verbose); if (! (ximageinfo= imageToXImage(disp, scrn, DefaultVisual(disp, scrn),