[PATCH setxkbmap] Eliminate limitations on path length.

Van de Bugger van.de.bugger at gmail.com
Tue Feb 15 12:55:28 PST 2011


...by using dynamically allocated buffers. No need in PATH_MAX,
MAXPATHLEN. No more "Path too long" errors.
---
 configure.ac |    2 +
 setxkbmap.c  |   89 ++++++++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 64 insertions(+), 27 deletions(-)

diff --git a/configure.ac b/configure.ac
index bc16554..2c4381f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,6 +51,8 @@ PKG_CHECK_MODULES(SETXKBMAP, xkbfile x11)
 # Allow checking code with lint, sparse, etc.
 XORG_WITH_LINT
 
+AC_CHECK_FUNCS([vasprintf])
+
 AC_CONFIG_FILES([
 	Makefile
 	man/Makefile])
diff --git a/setxkbmap.c b/setxkbmap.c
index 3d3b7d8..9996eed 100644
--- a/setxkbmap.c
+++ b/setxkbmap.c
@@ -23,7 +23,9 @@
  THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
  ********************************************************/
-
+ 
+#define _GNU_SOURCE
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <locale.h>
@@ -36,13 +38,7 @@
 #include <X11/extensions/XKBconfig.h>
 #include <X11/extensions/XKBrules.h>
 
-#ifndef PATH_MAX
-#ifdef MAXPATHLEN
-#define PATH_MAX MAXPATHLEN
-#else
-#define PATH_MAX 1024
-#endif
-#endif
+#include "config.h"
 
 #ifndef DFLT_XKB_CONFIG_ROOT
 #define DFLT_XKB_CONFIG_ROOT "/usr/share/X11/xkb"
@@ -170,6 +166,7 @@ static int deviceSpec = XkbUseCoreKbd;
 
 /***====================================================================***/
 
+char * rprintf( char const * format, ... );
 Bool addToList(list_t * list, char *newVal);
 void usage(int argc, char **argv);
 void dumpNames(Bool wantRules, Bool wantCNames);
@@ -189,6 +186,56 @@ void printKeymap(void);
 /***====================================================================***/
 
 /*
+    Like sprintf, but returns freshly allocated string instead writing it to
+    pre-allocated buffer. Do not forget to free returned strung.
+*/
+
+char *
+rprintf(char const * format, ...)
+{
+    va_list args;
+    char * buffer = NULL;
+    #ifdef HAVE_VASPRINTF
+        int rc;
+        va_start(args, format);
+        rc = vasprintf(&buffer, format, args);
+        va_end(args);
+        if (rc < 0)
+        {
+            /* It is not clear whether vasprintf sets errno or not. */
+            ERR1("`vasprintf' returned unexpected error (%d).\n", rc);
+            abort();
+        }
+    #else
+        int allocated = 0;
+        int required  = 100;
+        do 
+        {
+            buffer = realloc(buffer, required + 1);
+            if (buffer == NULL)
+            {
+                ERR("Out of memory.\n");
+                abort();
+            }
+            allocated = required + 1;
+            va_start(args, format);
+            required = vsnprintf(buffer, allocated, format, args);
+            va_end(args);
+            if (required < 0)
+            {
+                /* It is not clear whether vsnprintf sets errno or not. */
+                ERR1("`vsnprintf' returned unexpected error (%d).\n", required);
+                abort();
+            }
+        }
+        while (required >= allocated);
+    #endif
+    return buffer;
+}
+
+/***====================================================================***/
+
+/*
     If newVal is NULL or empty string, the list is cleared.
     Otherwise newVal is added to the end of the list (if it is not present in the list yet).
 */
@@ -623,7 +670,6 @@ FILE *
 findFileInPath(char *name, char *subdir)
 {
     register int i;
-    char buf[PATH_MAX];
     FILE *fp;
 
     if (name[0] == '/')
@@ -635,16 +681,11 @@ findFileInPath(char *name, char *subdir)
     }
     for (i = 0; (i < inclPath.num); i++)
     {
-        if (snprintf(buf, PATH_MAX, "%s/%s%s", inclPath.item[i], subdir, name) >=
-            PATH_MAX)
-        {
-            VMSG3(0, "Path too long (%s/%s%s). Ignored.\n", inclPath.item[i],
-                  subdir, name);
-            continue;
-        }
-        fp = fopen(buf, "r");
+        char * path = rprintf("%s/%s%s", inclPath.item[i], subdir, name);
+        fp = fopen(path, "r");
         if ((verbose > 7) || ((!fp) && (verbose > 5)))
-            MSG2("%s file %s\n", (fp ? "Found" : "Didn't find"), buf);
+            MSG2("%s file %s\n", (fp ? "Found" : "Didn't find"), path);
+        free(path);
         if (fp != NULL)
             return fp;
     }
@@ -824,7 +865,6 @@ applyRules(void)
     if (settings.model.src || settings.layout.src || settings.variant.src
         || options.item)
     {
-        char buf[PATH_MAX];
         XkbComponentNamesRec rnames;
 
         if (settings.variant.src < settings.layout.src)
@@ -852,14 +892,9 @@ applyRules(void)
              * we succeed with */
             for (i = 0; (i < inclPath.num) && (!rules); i++)
             {
-                if (snprintf(buf, PATH_MAX, "%s/rules/%s",
-                             inclPath.item[i], rfName) >= PATH_MAX)
-                {
-                    VMSG2(0, "Path too long (%s/rules/%s). Ignored.\n",
-                          inclPath.item[i], rfName);
-                    continue;
-                }
-                rules = XkbRF_Load(buf, settings.locale.value, True, True);
+                char * path = rprintf("%s/rules/%s", inclPath.item[i], rfName);
+                rules = XkbRF_Load(path, settings.locale.value, True, True);
+                free(path);
             }
         }
         if (!rules)
-- 
1.7.4







 


On Wed, 2011-02-16 at 07:40 +1000, Peter Hutterer wrote:
> On Wed, Feb 16, 2011 at 12:15:52AM +0300, Van de Bugger wrote:
> > From 0aaae5b3c0d6183e2791c30155bae40132a0c779 Mon Sep 17 00:00:00 2001
> > From: Van de Bugger <van.de.bugger at gmail.com>
> > Date: Tue, 15 Feb 2011 23:55:28 +0300
> > Subject: [PATCH setxkbmap] Eliminate limitations on path length.
> > 
> > ...by using dynamically allocated buffers. No need in PATH_MAX,
> > MAXPATHLEN. No more "Path too long" errors.
> > ---
> >  setxkbmap.c |   72 ++++++++++++++++++++++++++++++++++++----------------------
> >  1 files changed, 45 insertions(+), 27 deletions(-)
> > 
> > diff --git a/setxkbmap.c b/setxkbmap.c
> > index 3d3b7d8..6777b1b 100644
> > --- a/setxkbmap.c
> > +++ b/setxkbmap.c
> > @@ -24,6 +24,7 @@
> >  
> >   ********************************************************/
> >  
> > +#include <stdarg.h>
> >  #include <stdio.h>
> >  #include <stdlib.h>
> >  #include <locale.h>
> > @@ -36,14 +37,6 @@
> >  #include <X11/extensions/XKBconfig.h>
> >  #include <X11/extensions/XKBrules.h>
> >  
> > -#ifndef PATH_MAX
> > -#ifdef MAXPATHLEN
> > -#define PATH_MAX MAXPATHLEN
> > -#else
> > -#define PATH_MAX 1024
> > -#endif
> > -#endif
> > -
> >  #ifndef DFLT_XKB_CONFIG_ROOT
> >  #define DFLT_XKB_CONFIG_ROOT "/usr/share/X11/xkb"
> >  #endif
> > @@ -170,6 +163,7 @@ static int deviceSpec = XkbUseCoreKbd;
> >  
> >  /***====================================================================***/
> >  
> > +char * rprintf( char const * format, ... );
> >  Bool addToList(list_t * list, char *newVal);
> >  void usage(int argc, char **argv);
> >  void dumpNames(Bool wantRules, Bool wantCNames);
> > @@ -189,6 +183,42 @@ void printKeymap(void);
> >  /***====================================================================***/
> >  
> >  /*
> > +    Like sprintf, but returns freshly allocated string instead writing it to
> > +    pre-allocated buffer. Do not forget to free returned strung.
> > +*/
> 
> this sounds like a job for asprintf if we have it. I think the server has
> reimplementations for this on non-supporting platforms, maybe we can re-use
> those.
> 
> rest of the patch looks good though.
> 
> Cheers,
>   Peter
> 




More information about the xorg-devel mailing list