diff options
| author | Philipp Stephani | 2015-11-23 19:46:17 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2015-11-23 19:46:17 +0200 |
| commit | ccc16061acb4d1cdd7c2b0da71b98092002935aa (patch) | |
| tree | 70a2fda63e8e49261f8f155af609e14161cf9f2f /src | |
| parent | 50090b04a6a1d5c0e0e42399d32b8a8b661a61d8 (diff) | |
| download | emacs-ccc16061acb4d1cdd7c2b0da71b98092002935aa.tar.gz emacs-ccc16061acb4d1cdd7c2b0da71b98092002935aa.zip | |
Fix how strings are accepted from modules
* emacs-module.c (module_make_function, module_make_string): Use
make_multibyte_string.
(module_copy_string_contents): Encode before reading the byte
size. Return false if and only if an error occurred.
Diffstat (limited to 'src')
| -rw-r--r-- | src/emacs-module.c | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/src/emacs-module.c b/src/emacs-module.c index c8a0d89492a..f49802c2819 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c | |||
| @@ -25,6 +25,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 25 | #include <stddef.h> | 25 | #include <stddef.h> |
| 26 | #include <stdint.h> | 26 | #include <stdint.h> |
| 27 | #include <stdio.h> | 27 | #include <stdio.h> |
| 28 | #include <string.h> | ||
| 28 | 29 | ||
| 29 | #include "lisp.h" | 30 | #include "lisp.h" |
| 30 | #include "dynlib.h" | 31 | #include "dynlib.h" |
| @@ -386,9 +387,20 @@ module_make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity, | |||
| 386 | envptr->data = data; | 387 | envptr->data = data; |
| 387 | 388 | ||
| 388 | Lisp_Object envobj = make_save_ptr (envptr); | 389 | Lisp_Object envobj = make_save_ptr (envptr); |
| 390 | Lisp_Object doc; | ||
| 391 | if (documentation == NULL) | ||
| 392 | doc = Qnil; | ||
| 393 | else | ||
| 394 | { | ||
| 395 | ptrdiff_t nbytes = strlen (documentation); | ||
| 396 | ptrdiff_t nchars, ignored_nbytes; | ||
| 397 | parse_str_as_multibyte (documentation, nbytes, &nchars, &ignored_nbytes); | ||
| 398 | doc = make_multibyte_string (documentation, nchars, nbytes); | ||
| 399 | } | ||
| 400 | |||
| 389 | Lisp_Object ret = list4 (Qlambda, | 401 | Lisp_Object ret = list4 (Qlambda, |
| 390 | list2 (Qand_rest, Qargs), | 402 | list2 (Qand_rest, Qargs), |
| 391 | documentation ? build_string (documentation) : Qnil, | 403 | doc, |
| 392 | list3 (module_call_func, | 404 | list3 (module_call_func, |
| 393 | envobj, | 405 | envobj, |
| 394 | Qargs)); | 406 | Qargs)); |
| @@ -515,21 +527,34 @@ module_copy_string_contents (emacs_env *env, emacs_value value, char *buffer, | |||
| 515 | return false; | 527 | return false; |
| 516 | } | 528 | } |
| 517 | 529 | ||
| 518 | ptrdiff_t raw_size = SBYTES (lisp_str); | 530 | Lisp_Object lisp_str_utf8 = ENCODE_UTF_8 (lisp_str); |
| 531 | ptrdiff_t raw_size = SBYTES (lisp_str_utf8); | ||
| 532 | if (raw_size == PTRDIFF_MAX) | ||
| 533 | { | ||
| 534 | module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); | ||
| 535 | return false; | ||
| 536 | } | ||
| 537 | ptrdiff_t required_buf_size = raw_size + 1; | ||
| 538 | |||
| 539 | eassert (length != NULL); | ||
| 519 | 540 | ||
| 520 | /* Emacs internal encoding is more-or-less UTF8, let's assume utf8 | 541 | if (buffer == NULL) |
| 521 | encoded emacs string are the same byte size. */ | 542 | { |
| 543 | *length = required_buf_size; | ||
| 544 | return true; | ||
| 545 | } | ||
| 546 | |||
| 547 | eassert (*length >= 0); | ||
| 522 | 548 | ||
| 523 | if (!buffer || length == 0 || *length-1 < raw_size) | 549 | if (*length < required_buf_size) |
| 524 | { | 550 | { |
| 525 | *length = raw_size + 1; | 551 | *length = required_buf_size; |
| 552 | module_non_local_exit_signal_1 (env, Qargs_out_of_range, Qnil); | ||
| 526 | return false; | 553 | return false; |
| 527 | } | 554 | } |
| 528 | 555 | ||
| 529 | Lisp_Object lisp_str_utf8 = ENCODE_UTF_8 (lisp_str); | 556 | *length = required_buf_size; |
| 530 | eassert (raw_size == SBYTES (lisp_str_utf8)); | 557 | memcpy (buffer, SDATA (lisp_str_utf8), raw_size); |
| 531 | *length = raw_size + 1; | ||
| 532 | memcpy (buffer, SDATA (lisp_str_utf8), SBYTES (lisp_str_utf8)); | ||
| 533 | buffer[raw_size] = 0; | 558 | buffer[raw_size] = 0; |
| 534 | 559 | ||
| 535 | return true; | 560 | return true; |
| @@ -541,13 +566,14 @@ module_make_string (emacs_env *env, const char *str, ptrdiff_t length) | |||
| 541 | check_main_thread (); | 566 | check_main_thread (); |
| 542 | eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); | 567 | eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); |
| 543 | MODULE_HANDLE_SIGNALS; | 568 | MODULE_HANDLE_SIGNALS; |
| 544 | if (length > PTRDIFF_MAX) | 569 | if (length > STRING_BYTES_BOUND) |
| 545 | { | 570 | { |
| 546 | module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); | 571 | module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); |
| 547 | return NULL; | 572 | return NULL; |
| 548 | } | 573 | } |
| 549 | /* Assume STR is utf8 encoded. */ | 574 | ptrdiff_t nchars, ignored_nbytes; |
| 550 | return lisp_to_value (env, make_string (str, length)); | 575 | parse_str_as_multibyte (str, length, &nchars, &ignored_nbytes); |
| 576 | return lisp_to_value (env, make_multibyte_string (str, nchars, length)); | ||
| 551 | } | 577 | } |
| 552 | 578 | ||
| 553 | static emacs_value | 579 | static emacs_value |