summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2009-11-24 15:31:48 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2009-11-25 10:57:07 +1000
commit1b127ab8429616adf9ec31ba4d8bdd9af6e104a9 (patch)
treea81139dafed33b48f977d14a3d6a35cfcb1dbc5c
parent8806375ed72a3cd465fe0a49ead079a334accd6b (diff)
Xi: when deleting all properties, reset property handler to NULL.
Trying to unregister property handlers during the device closure process leads to invalid memory accesses. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Keith Packard <keithp@keithp.com>
-rw-r--r--Xi/xiproperty.c2
-rw-r--r--test/input.c54
2 files changed, 56 insertions, 0 deletions
diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 482185703..ecb326ee3 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -630,6 +630,8 @@ XIDeleteAllDeviceProperties (DeviceIntPtr device)
xfree(curr_handler);
curr_handler = next_handler;
}
+
+ device->properties.handlers = NULL;
}
diff --git a/test/input.c b/test/input.c
index 71e1504f1..2de55bc63 100644
--- a/test/input.c
+++ b/test/input.c
@@ -716,6 +716,59 @@ static void include_byte_padding_macros(void)
}
+static void xi_unregister_handlers(void)
+{
+ DeviceIntRec dev;
+ int handler;
+
+ memset(&dev, 0, sizeof(dev));
+
+ handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+ g_assert(handler == 1);
+ handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+ g_assert(handler == 2);
+ handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+ g_assert(handler == 3);
+
+ g_test_message("Unlinking from front.");
+
+ XIUnregisterPropertyHandler(&dev, 4); /* NOOP */
+ g_assert(dev.properties.handlers->id == 3);
+ XIUnregisterPropertyHandler(&dev, 3);
+ g_assert(dev.properties.handlers->id == 2);
+ XIUnregisterPropertyHandler(&dev, 2);
+ g_assert(dev.properties.handlers->id == 1);
+ XIUnregisterPropertyHandler(&dev, 1);
+ g_assert(dev.properties.handlers == NULL);
+
+ handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+ g_assert(handler == 4);
+ handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+ g_assert(handler == 5);
+ handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+ g_assert(handler == 6);
+ XIUnregisterPropertyHandler(&dev, 3); /* NOOP */
+ g_assert(dev.properties.handlers->next->next->next == NULL);
+ XIUnregisterPropertyHandler(&dev, 4);
+ g_assert(dev.properties.handlers->next->next == NULL);
+ XIUnregisterPropertyHandler(&dev, 5);
+ g_assert(dev.properties.handlers->next == NULL);
+ XIUnregisterPropertyHandler(&dev, 6);
+ g_assert(dev.properties.handlers == NULL);
+
+ handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+ g_assert(handler == 7);
+ handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+ g_assert(handler == 8);
+ handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+ g_assert(handler == 9);
+
+ XIDeleteAllDeviceProperties(&dev);
+ g_assert(dev.properties.handlers == NULL);
+ XIUnregisterPropertyHandler(&dev, 7); /* NOOP */
+
+}
+
int main(int argc, char** argv)
{
g_test_init(&argc, &argv,NULL);
@@ -727,6 +780,7 @@ int main(int argc, char** argv)
g_test_add_func("/dix/input/xi2-struct-sizes", xi2_struct_sizes);
g_test_add_func("/dix/input/grab_matching", dix_grab_matching);
g_test_add_func("/include/byte_padding_macros", include_byte_padding_macros);
+ g_test_add_func("/Xi/xiproperty/register-unregister", xi_unregister_handlers);
return g_test_run();
}