diff options
| author | Philipp Stephani | 2017-07-04 22:50:46 +0200 |
|---|---|---|
| committer | Philipp Stephani | 2017-07-08 15:25:01 +0200 |
| commit | b7dab24b7953f7a31b806f83e15043c94aaa7745 (patch) | |
| tree | fc31284ef0fac82accddc573069652b1c8adccf0 /test/data | |
| parent | a87d767c7acc43b3679d87d2d225b1edeb69326c (diff) | |
| download | emacs-b7dab24b7953f7a31b806f83e15043c94aaa7745.tar.gz emacs-b7dab24b7953f7a31b806f83e15043c94aaa7745.zip | |
Module assertions: check for garbage collections
It's technically possible to write a user pointer finalizer that calls
into Emacs module functions. This would be disastrous because it
would allow arbitrary Lisp code to run during garbage collection.
Therefore extend the module assertions to check for this case.
* src/emacs-module.c (module_assert_thread): Also check whether a
garbage collection is in progress.
* test/data/emacs-module/mod-test.c (invalid_finalizer)
(Fmod_test_invalid_finalizer): New test module functions.
(emacs_module_init): Register new test function.
* test/src/emacs-module-tests.el (module--test-assertion)
(module--with-temp-directory): New helper macros.
(module--test-assertions--load-non-live-object): Rename existing
unit test, use helper macros.
(module--test-assertions--call-emacs-from-gc): New unit test.
Diffstat (limited to 'test/data')
| -rw-r--r-- | test/data/emacs-module/mod-test.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c index eee9466c5d6..42e1c2bd4ae 100644 --- a/test/data/emacs-module/mod-test.c +++ b/test/data/emacs-module/mod-test.c | |||
| @@ -235,6 +235,27 @@ Fmod_test_invalid_load (emacs_env *env, ptrdiff_t nargs, emacs_value *args, | |||
| 235 | return invalid_stored_value; | 235 | return invalid_stored_value; |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | /* An invalid finalizer: Finalizers are run during garbage collection, | ||
| 239 | where Lisp code can’t be executed. -module-assertions tests for | ||
| 240 | this case. */ | ||
| 241 | |||
| 242 | static emacs_env *current_env; | ||
| 243 | |||
| 244 | static void | ||
| 245 | invalid_finalizer (void *ptr) | ||
| 246 | { | ||
| 247 | current_env->intern (current_env, "nil"); | ||
| 248 | } | ||
| 249 | |||
| 250 | static emacs_value | ||
| 251 | Fmod_test_invalid_finalizer (emacs_env *env, ptrdiff_t nargs, emacs_value *args, | ||
| 252 | void *data) | ||
| 253 | { | ||
| 254 | current_env = env; | ||
| 255 | env->make_user_ptr (env, invalid_finalizer, NULL); | ||
| 256 | return env->funcall (env, env->intern (env, "garbage-collect"), 0, NULL); | ||
| 257 | } | ||
| 258 | |||
| 238 | 259 | ||
| 239 | /* Lisp utilities for easier readability (simple wrappers). */ | 260 | /* Lisp utilities for easier readability (simple wrappers). */ |
| 240 | 261 | ||
| @@ -300,6 +321,8 @@ emacs_module_init (struct emacs_runtime *ert) | |||
| 300 | DEFUN ("mod-test-vector-eq", Fmod_test_vector_eq, 2, 2, NULL, NULL); | 321 | DEFUN ("mod-test-vector-eq", Fmod_test_vector_eq, 2, 2, NULL, NULL); |
| 301 | DEFUN ("mod-test-invalid-store", Fmod_test_invalid_store, 0, 0, NULL, NULL); | 322 | DEFUN ("mod-test-invalid-store", Fmod_test_invalid_store, 0, 0, NULL, NULL); |
| 302 | DEFUN ("mod-test-invalid-load", Fmod_test_invalid_load, 0, 0, NULL, NULL); | 323 | DEFUN ("mod-test-invalid-load", Fmod_test_invalid_load, 0, 0, NULL, NULL); |
| 324 | DEFUN ("mod-test-invalid-finalizer", Fmod_test_invalid_finalizer, 0, 0, | ||
| 325 | NULL, NULL); | ||
| 303 | 326 | ||
| 304 | #undef DEFUN | 327 | #undef DEFUN |
| 305 | 328 | ||