state, context: allow passing NULL to *_unref() For error handling code, it's nice to be able to pass NULL to these function without worrying about segfaults ensuing. free() sets the precedent here. Also document this fact. Signed-off-by: Ran Benita <ran234@gmail.com>
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
diff --git a/src/context.c b/src/context.c
index 53028a1..a846b8f 100644
--- a/src/context.c
+++ b/src/context.c
@@ -206,7 +206,7 @@ xkb_context_ref(struct xkb_context *ctx)
XKB_EXPORT void
xkb_context_unref(struct xkb_context *ctx)
{
- if (--ctx->refcnt > 0)
+ if (!ctx || --ctx->refcnt > 0)
return;
xkb_context_include_path_clear(ctx);
diff --git a/src/state.c b/src/state.c
index eaa1f10..48b2132 100644
--- a/src/state.c
+++ b/src/state.c
@@ -583,7 +583,7 @@ xkb_state_ref(struct xkb_state *state)
XKB_EXPORT void
xkb_state_unref(struct xkb_state *state)
{
- if (--state->refcnt > 0)
+ if (!state || --state->refcnt > 0)
return;
xkb_keymap_unref(state->keymap);
diff --git a/test/state.c b/test/state.c
index d23b94c..83a8f45 100644
--- a/test/state.c
+++ b/test/state.c
@@ -339,6 +339,11 @@ main(void)
assert(context);
+ /* Make sure these are allowed. */
+ xkb_context_unref(NULL);
+ xkb_keymap_unref(NULL);
+ xkb_state_unref(NULL);
+
keymap = test_compile_rules(context, "evdev", "pc104", "us,ru", NULL, "grp:menu_toggle");
assert(keymap);
diff --git a/xkbcommon/xkbcommon.h b/xkbcommon/xkbcommon.h
index fe5c789..65c4dcc 100644
--- a/xkbcommon/xkbcommon.h
+++ b/xkbcommon/xkbcommon.h
@@ -439,6 +439,8 @@ xkb_context_ref(struct xkb_context *context);
/**
* Release a reference on a context, and possibly free it.
*
+ * @param context The context. If it is NULL, this function does nothing.
+ *
* @memberof xkb_context
*/
void
@@ -737,6 +739,8 @@ xkb_keymap_ref(struct xkb_keymap *keymap);
/**
* Release a reference on a keymap, and possibly free it.
*
+ * @param keymap The keymap. If it is NULL, this function does nothing.
+ *
* @memberof xkb_keymap
*/
void
@@ -991,6 +995,8 @@ xkb_state_ref(struct xkb_state *state);
/**
* Release a reference on a keybaord state object, and possibly free it.
*
+ * @param state The state. If it is NULL, this function does nothing.
+ *
* @memberof xkb_state
*/
void