[PATCH] xkb: when copying the keymap, make sure the structs default to 0/NULL.

Peter Hutterer mailinglists at who-t.net
Wed Feb 6 21:33:07 PST 2008


Finally found the bug. Turns out that when copying keymaps, parts of 
structs remain unintialised. this is a bad idea if you're trying to free 
various pointers lateron (in my case dst->geom->sections->doodads).

Please review the following patch, I'm not 100% sure on the memset in 
hunk 4.

Cheers,
   Peter



 From 0d042bae64ad96e783c71ae9492ffd7f80d006cd Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter at cs.unisa.edu.au>
Date: Thu, 7 Feb 2008 15:48:04 +1030
Subject: [PATCH] xkb: when copying the keymap, make sure the structs 
default to 0/NULL.

It actually does help if a pointer is NULL rather than pointing to nirvana
when you're trying to free it lateron. Who would have thought?
---
  xkb/xkbUtils.c |   29 +++++++++++++++++++++--------
  1 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 68ecb32..c67a657 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -1733,9 +1733,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool 
sendNotifies)
          else {
              if (dst->geom->sz_shapes) {
                  xfree(dst->geom->shapes);
-                dst->geom->shapes = NULL;
              }
-
+            dst->geom->shapes = NULL;
              dst->geom->num_shapes = 0;
              dst->geom->sz_shapes = 0;
          }
@@ -1752,11 +1751,15 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, 
Bool sendNotifies)
                       j++, drow++) {
                      if (drow->num_keys)
                          xfree(drow->keys);
+
+                    drow->keys = NULL;
                  }

                  if (dsection->num_rows)
                      xfree(dsection->rows);

+                dsection->rows = NULL;
+
                  /* cut and waste from geom/doodad below. */
                  for (j = 0, ddoodad = dsection->doodads;
                       j < dsection->num_doodads;
@@ -1781,9 +1784,12 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, 
Bool sendNotifies)

                  if (dsection->num_doodads)
                      xfree(dsection->doodads);
+
+                dsection->doodads = NULL;
              }

              dst->geom->num_sections = 0;
+            dst->geom->sections = NULL;
          }

          if (src->geom->num_sections) {
@@ -1795,6 +1801,7 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool 
sendNotifies)
                  tmp = xalloc(src->geom->num_sections * 
sizeof(XkbSectionRec));
              if (!tmp)
                  return FALSE;
+            memset(tmp, 0, src->geom->num_sections * 
sizeof(XkbSectionRec));
              dst->geom->sections = tmp;
              dst->geom->num_sections = src->geom->num_sections;

@@ -1809,6 +1816,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool 
sendNotifies)
                          return FALSE;
                      dsection->rows = tmp;
                  }
+                dsection->num_rows = ssection->num_rows;
+
                  for (j = 0, srow = ssection->rows, drow = dsection->rows;
                       j < ssection->num_rows;
                       j++, srow++, drow++) {
@@ -1829,7 +1838,9 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool 
sendNotifies)
                      if (!tmp)
                          return FALSE;
                      dsection->doodads = tmp;
-                }
+                } else
+                    dsection->doodads = NULL;
+
                  for (k = 0,
                        sdoodad = ssection->doodads,
                        ddoodad = dsection->doodads;
@@ -1857,9 +1868,9 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool 
sendNotifies)
          else {
              if (dst->geom->sz_sections) {
                  xfree(dst->geom->sections);
-                dst->geom->sections = NULL;
              }

+            dst->geom->sections = NULL;
              dst->geom->num_sections = 0;
              dst->geom->sz_sections = 0;
          }
@@ -1888,6 +1899,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool 
sendNotifies)
                      }
                  }
              }
+            dst->geom->num_doodads = 0;
+            dst->geom->doodads = NULL;
          }

          if (src->geom->num_doodads) {
@@ -1900,7 +1913,7 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool 
sendNotifies)
                                sizeof(XkbDoodadRec));
              if (!tmp)
                  return FALSE;
-            bzero(tmp, src->geom->num_doodads * sizeof(XkbDoodadRec));
+            memset(tmp, 0, src->geom->num_doodads * sizeof(XkbDoodadRec));
              dst->geom->doodads = tmp;

              dst->geom->sz_doodads = src->geom->num_doodads;
@@ -1929,9 +1942,9 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool 
sendNotifies)
          else {
              if (dst->geom->sz_doodads) {
                  xfree(dst->geom->doodads);
-                dst->geom->doodads = NULL;
              }

+            dst->geom->doodads = NULL;
              dst->geom->num_doodads = 0;
              dst->geom->sz_doodads = 0;
          }
@@ -1961,8 +1974,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool 
sendNotifies)
          else {
              if (dst->geom->sz_key_aliases && dst->geom->key_aliases) {
                  xfree(dst->geom->key_aliases);
-                dst->geom->key_aliases = NULL;
              }
+            dst->geom->key_aliases = NULL;
              dst->geom->num_key_aliases = 0;
              dst->geom->sz_key_aliases = 0;
          }
@@ -1993,8 +2006,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool 
sendNotifies)
          else {
              if (dst->geom->label_font) {
                  xfree(dst->geom->label_font);
-                dst->geom->label_font = NULL;
              }
+            dst->geom->label_font = NULL;
              dst->geom->label_color = NULL;
              dst->geom->base_color = NULL;
          }
-- 
1.5.3




More information about the xorg mailing list