diff options
author | Philipp Stephani <phst@google.com> | 2020-12-12 23:21:18 +0100 |
---|---|---|
committer | Philipp Stephani <phst@google.com> | 2020-12-12 23:28:22 +0100 |
commit | 52e3ac6303292fdea8f441821a40f8f5ca31e3de (patch) | |
tree | bbf58178863524a092ef4230fcc1ffe73687d3c9 /src/emacs-module.c | |
parent | 4bf98aecffe57648d15db90718134b00ac87ec3b (diff) | |
download | emacs-52e3ac6303292fdea8f441821a40f8f5ca31e3de.tar.gz |
Document and enforce some properties for strings created by modules.
When creating multibyte or unibyte strings, we should guarantee the
following invariants:
- When creating empty strings, a NULL data pointer should be allowed.
This often arises in practice if the string length isn't known in
advance, and we don't want to unnecessarily trigger undefined
behavior. Since functions like memcpy might not accept NULL
pointers, use the canonical empty string objects in this case.
- Nonzero strings should be guaranteed to be unique and mutable.
These are the same guarantees expected from Lisp functions such as
'make-string' or 'unibyte-string'. On the other hand, empty strings
might not be unique.
* src/emacs-module.c (module_make_string)
(module_make_unibyte_string): Correctly handle empty strings.
* test/src/emacs-module-resources/mod-test.c (Fmod_test_make_string):
New test function.
(emacs_module_init): Expose it.
* test/src/emacs-module-tests.el (mod-test-make-string/empty)
(mod-test-make-string/nonempty): New unit tests.
* doc/lispref/internals.texi (Module Values): Document properties and
corner cases for strings.
Diffstat (limited to 'src/emacs-module.c')
-rw-r--r-- | src/emacs-module.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/src/emacs-module.c b/src/emacs-module.c index 0f3ef59fd8c..b7cd835c83c 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -784,7 +784,8 @@ module_make_string (emacs_env *env, const char *str, ptrdiff_t len) MODULE_FUNCTION_BEGIN (NULL); if (! (0 <= len && len <= STRING_BYTES_BOUND)) overflow_error (); - Lisp_Object lstr = module_decode_utf_8 (str, len); + Lisp_Object lstr + = len == 0 ? empty_multibyte_string : module_decode_utf_8 (str, len); return lisp_to_value (env, lstr); } @@ -794,9 +795,8 @@ module_make_unibyte_string (emacs_env *env, const char *str, ptrdiff_t length) MODULE_FUNCTION_BEGIN (NULL); if (! (0 <= length && length <= STRING_BYTES_BOUND)) overflow_error (); - Lisp_Object lstr = make_uninit_string (length); - memcpy (SDATA (lstr), str, length); - SDATA (lstr)[length] = 0; + Lisp_Object lstr + = length == 0 ? empty_unibyte_string : make_unibyte_string (str, length); return lisp_to_value (env, lstr); } |