[gembud] [PATCH] OpenMotif patch to fix garp/nmap2 segfaults on Fedora/Ubuntu

Hi.

The patch to 'Xmos.c' below fixed the immediate segfaults seen when
trying to run either garp or nmap2 in Fedora 15. The patch was
generated against the openmotif-2.3.3 release, and 'Xmos.c' is in the
'lib/Xm' subdirectory. Once the code was patched, built, and installed,
I was able to start both programs succesfully; previously I was using
some RPM builds from the OpenMotif website produced for an earlier
Fedora release. The Fedora 15 box is running a 32-bit version of Linux.
I'm hoping the fixed code will work on Fedora 16 once it arrives.

We've also been running Garp on some 64-bit Ubuntu machines. In the
Natty Narwhal release we could use the 'libmotif' packages provided by
Ubuntu, but once we upgraded to the new Oneiric Ocelot release the
programs would segfault at startup. By installing a locally built
openmotif-2.3.3 release with the patch below, though, once again garp
and nmap2 would start and run.

I've not been able to determine what change(s) between the Fedora/Ubuntu
releases cause the original sprintf() call to fail, but by splitting
up the values in the 'PATH_DEFAULT' and 'XAPPLRESDIR' formatting strings
into smaller components, and then generating the final formatted string
by using a temporary buffer and multiple sprintf() calls, the code
executes without segfaulting. The patch could be improved by moving the
common variable declarations earlier in the function, and testing
the malloc() call does not fail.

In addition to the 'Xmos.c' patch I'm also sending a one-line fix to the
'FontS.c' file also in the same directory. This fix corrects a classic
c-language array access error - the valid index for this array is '0',
not '1'.


--- Xmos.c.orig 2008-08-29 13:44:39.000000000 +0000
+++ Xmos.c      2011-11-07 14:55:01.191008780 +0000
@@ -1286,23 +1286,104 @@
          old_path = (char *)getenv ("XAPPLRESDIR");
          if (old_path == NULL) 
            {
-             path = XtCalloc(1, (9*strlen(homedir) + strlen(PATH_DEFAULT) +
-                                 8*strlen(libdir) + strlen(incdir) + 1));
-             sprintf(path, PATH_DEFAULT, homedir, homedir, homedir,
-                     homedir, homedir, homedir, homedir, homedir, homedir,
-                     libdir, libdir, libdir, libdir, libdir, libdir, libdir,
-                     libdir, incdir);
+              size_t asz;
+              size_t len;
+              char * buffer;
+             asz = (9*strlen(homedir) + strlen(PATH_DEFAULT) +
+                    8*strlen(libdir) + strlen(incdir) + 1);
+             buffer = malloc(asz);
+              len = 0;
+              len += sprintf(buffer + (int)len,
+                               "%%P%%S:%s/%%L/%%T/%%N/%%P%%S:", homedir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%l_%%t/%%T/%%N/%%P%%S:", homedir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%l/%%T/%%N/%%P%%S:", homedir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%T/%%N/%%P%%S:", homedir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%L/%%T/%%P%%S:", homedir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%l_%%t/%%T/%%P%%S:", homedir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%l/%%T/%%P%%S:", homedir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%T/%%P%%S:", homedir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%P%%S:", homedir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%L/%%T/%%N/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%l_%%t/%%T/%%N/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%l/%%T/%%N/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%T/%%N/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%L/%%T/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%l_%%t/%%T/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%l/%%T/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%T/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                               "%s/%%T/%%P%%S", incdir);
+              path = XtCalloc(1, asz);
+              strcpy(path, buffer);
+              free(buffer);
            } 
          else
            {
-             path = XtCalloc(1, (8*strlen(old_path) + 2*strlen(homedir) +
-                                 strlen(XAPPLRES_DEFAULT) + 8*strlen(libdir) +
-                                 strlen(incdir) + 1));
-             sprintf(path, XAPPLRES_DEFAULT, 
-                     old_path, old_path, old_path, old_path, old_path, 
-                     old_path, old_path, old_path, homedir, homedir,
-                     libdir, libdir, libdir, libdir, libdir, libdir, libdir,
-                     libdir, incdir);
+              size_t asz;
+              size_t len;
+              char * buffer;
+             asz = (8*strlen(old_path) + 2*strlen(homedir) +
+                    strlen(XAPPLRES_DEFAULT) + 8*strlen(libdir) +
+                    strlen(incdir) + 1);
+              buffer = malloc(asz);
+              len = 0;
+              len += sprintf(buffer + (int)len,
+                             "%%P%%S:%s/%%L/%%T/%%N/%%P%%S:", old_path);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%l_%%t/%%T/%%N/%%P%%S:", old_path);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%l/%%T/%%N/%%P%%S:", old_path);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%T/%%N/%%P%%S:", old_path);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%L/%%T/%%P%%S:", old_path);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%l_%%t/%%T/%%P%%S:", old_path);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%l/%%T/%%P%%S:", old_path);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%T/%%P%%S:", old_path);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%T/%%P%%S:", homedir);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%P%%S:", homedir);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%L/%%T/%%N/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%l_%%t/%%T/%%N/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%l/%%T/%%N/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%T/%%N/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%L/%%T/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%l_%%t/%%T/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%l/%%T/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%T/%%P%%S:", libdir);
+              len += sprintf(buffer + (int)len,
+                             "%s/%%T/%%P%%S", incdir);
+              path = XtCalloc(1, asz);
+              strcpy(path, buffer);
+              free(buffer);
            }
        } 
       else

--- lib/Xm/FontS.c.orig 2011-11-06 19:24:05.317118037 +0000
+++ lib/Xm/FontS.c      2011-11-04 18:01:06.507524410 +0000
@@ -1863,7 +1863,7 @@
                String params[1];
                Cardinal num = 1;
                
-               params[1] = new_font;
+               params[0] = new_font;
                dbg(); _XmWarningMsg((Widget) fsw, XmNbadXlfdFont,
                        XmNbadXlfdFontMsg, params, num);
            }