Don't return a static buffer in public API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
diff --git a/include/X11/extensions/XKBcommon.h b/include/X11/extensions/XKBcommon.h
index c1bc270..0b6fb77 100644
--- a/include/X11/extensions/XKBcommon.h
+++ b/include/X11/extensions/XKBcommon.h
@@ -797,15 +797,11 @@ xkb_canonicalise_components(struct xkb_component_names * names,
* Converts a keysym to a string; will return unknown Unicode codepoints
* as "Ua1b2", and other unknown keysyms as "0xabcd1234".
*
- * The string returned may become invalidated after the next call to
- * xkb_keysym_to_string: if you need to preserve it, then you must
- * duplicate it.
- *
* This is uint32_t rather than KeySym, as KeySym changes size between
* client and server (no, really).
*/
-_X_EXPORT extern char *
-xkb_keysym_to_string(uint32_t ks);
+_X_EXPORT extern void
+xkb_keysym_to_string(uint32_t ks, char *buffer, size_t size);
/*
* See xkb_keysym_to_string comments: this function will accept any string
diff --git a/src/keysym.c b/src/keysym.c
index 9316fc1..9fd3764 100644
--- a/src/keysym.c
+++ b/src/keysym.c
@@ -37,21 +37,22 @@ authorization from the authors.
#include "ks_tables.h"
-char *
-xkb_keysym_to_string(uint32_t ks)
+void
+xkb_keysym_to_string(uint32_t ks, char *buffer, size_t size)
{
int i, n, h, idx;
const unsigned char *entry;
- static char ret[11];
unsigned char val1, val2, val3, val4;
- if ((ks & ((unsigned long) ~0x1fffffff)) != 0)
- return NULL;
+ if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
+ snprintf(buffer, size, "Invalid");
+ return;
+ }
/* Not listed in keysymdef.h for hysterical raisins. */
if (ks == NoSymbol) {
- sprintf(ret, "NoSymbol");
- return ret;
+ snprintf(buffer, size, "NoSymbol");
+ return;
}
/* Try to find it in our hash table. */
@@ -68,8 +69,10 @@ xkb_keysym_to_string(uint32_t ks)
entry = &_XkeyTable[idx];
if ((entry[0] == val1) && (entry[1] == val2) &&
- (entry[2] == val3) && (entry[3] == val4))
- return ((char *)entry + 4);
+ (entry[2] == val3) && (entry[3] == val4)) {
+ snprintf(buffer, size, "%s", entry + 4);
+ return;
+ }
if (!--n)
break;
@@ -80,15 +83,12 @@ xkb_keysym_to_string(uint32_t ks)
}
}
- /* Unnamed Unicode codepoint. */
- if (ks >= 0x01000100 && ks <= 0x0110ffff) {
- sprintf(ret, "U%lx", ks & 0xffffffUL);
- return ret;
- }
-
- /* Unnamed, non-Unicode, symbol (shouldn't generally happen). */
- sprintf(ret, "0x%08x", ks);
- return ret;
+ if (ks >= 0x01000100 && ks <= 0x0110ffff)
+ /* Unnamed Unicode codepoint. */
+ snprintf(buffer, size, "U%lx", ks & 0xffffffUL);
+ else
+ /* Unnamed, non-Unicode, symbol (shouldn't generally happen). */
+ snprintf(buffer, size, "0x%08x", ks);
}
uint32_t
diff --git a/src/text.c b/src/text.c
index fc3cc45..1f82979 100644
--- a/src/text.c
+++ b/src/text.c
@@ -281,7 +281,11 @@ XkbcActionTypeText(unsigned type)
char *
XkbcKeysymText(uint32_t sym)
{
- return xkb_keysym_to_string(sym);
+ static char buffer[16];
+
+ xkb_keysym_to_string(sym, buffer, sizeof buffer);
+
+ return buffer;
}
char *
diff --git a/test/xkey.c b/test/xkey.c
index 9d7a08f..78baedd 100644
--- a/test/xkey.c
+++ b/test/xkey.c
@@ -15,8 +15,10 @@ static void print_keysym(const char *s)
static void print_string(KeySym ks)
{
- char *s = xkb_keysym_to_string(ks);
- printf("%s\n", s ? s : "NULL");
+ char s[16];
+
+ xkb_keysym_to_string(ks, s, sizeof s);
+ printf("%s\n", s);
}
int main(int argc, char *argv[])