diff options
| author | Eli Zaretskii | 2016-08-16 17:36:27 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2016-08-16 17:36:27 +0300 |
| commit | 4225b786746e170477ddd64deaf18facf11955f4 (patch) | |
| tree | acb46f03edc4638a1f01245eeb0aec088a749982 /src/doc.c | |
| parent | 8c2946e29b38fa3e0dff6b4d402ba0fda0e03c9b (diff) | |
| download | emacs-4225b786746e170477ddd64deaf18facf11955f4.tar.gz emacs-4225b786746e170477ddd64deaf18facf11955f4.zip | |
Avoid segfaults due to quoting in 'substitute-command-keys'
* src/doc.c (Fsubstitute_command_keys): Correct character counts
when the input string is unibyte. (Bug#24206)
Diffstat (limited to 'src/doc.c')
| -rw-r--r-- | src/doc.c | 20 |
1 files changed, 16 insertions, 4 deletions
| @@ -750,7 +750,7 @@ Otherwise, return a new string. */) | |||
| 750 | unsigned char const *start; | 750 | unsigned char const *start; |
| 751 | ptrdiff_t length, length_byte; | 751 | ptrdiff_t length, length_byte; |
| 752 | Lisp_Object name; | 752 | Lisp_Object name; |
| 753 | bool multibyte; | 753 | bool multibyte, pure_ascii; |
| 754 | ptrdiff_t nchars; | 754 | ptrdiff_t nchars; |
| 755 | 755 | ||
| 756 | if (NILP (string)) | 756 | if (NILP (string)) |
| @@ -764,6 +764,11 @@ Otherwise, return a new string. */) | |||
| 764 | enum text_quoting_style quoting_style = text_quoting_style (); | 764 | enum text_quoting_style quoting_style = text_quoting_style (); |
| 765 | 765 | ||
| 766 | multibyte = STRING_MULTIBYTE (string); | 766 | multibyte = STRING_MULTIBYTE (string); |
| 767 | /* Pure-ASCII unibyte input strings should produce unibyte strings | ||
| 768 | if substitution doesn't yield non-ASCII bytes, otherwise they | ||
| 769 | should produce multibyte strings. */ | ||
| 770 | pure_ascii = SBYTES (string) == count_size_as_multibyte (SDATA (string), | ||
| 771 | SCHARS (string)); | ||
| 767 | nchars = 0; | 772 | nchars = 0; |
| 768 | 773 | ||
| 769 | /* KEYMAP is either nil (which means search all the active keymaps) | 774 | /* KEYMAP is either nil (which means search all the active keymaps) |
| @@ -945,8 +950,11 @@ Otherwise, return a new string. */) | |||
| 945 | 950 | ||
| 946 | subst_string: | 951 | subst_string: |
| 947 | start = SDATA (tem); | 952 | start = SDATA (tem); |
| 948 | length = SCHARS (tem); | ||
| 949 | length_byte = SBYTES (tem); | 953 | length_byte = SBYTES (tem); |
| 954 | if (multibyte || pure_ascii) | ||
| 955 | length = SCHARS (tem); | ||
| 956 | else | ||
| 957 | length = length_byte; | ||
| 950 | subst: | 958 | subst: |
| 951 | nonquotes_changed = true; | 959 | nonquotes_changed = true; |
| 952 | subst_quote: | 960 | subst_quote: |
| @@ -965,11 +973,15 @@ Otherwise, return a new string. */) | |||
| 965 | } | 973 | } |
| 966 | } | 974 | } |
| 967 | else if ((strp[0] == '`' || strp[0] == '\'') | 975 | else if ((strp[0] == '`' || strp[0] == '\'') |
| 968 | && quoting_style == CURVE_QUOTING_STYLE) | 976 | && quoting_style == CURVE_QUOTING_STYLE |
| 977 | && multibyte) | ||
| 969 | { | 978 | { |
| 970 | start = (unsigned char const *) (strp[0] == '`' ? uLSQM : uRSQM); | 979 | start = (unsigned char const *) (strp[0] == '`' ? uLSQM : uRSQM); |
| 971 | length = 1; | ||
| 972 | length_byte = sizeof uLSQM - 1; | 980 | length_byte = sizeof uLSQM - 1; |
| 981 | if (multibyte || pure_ascii) | ||
| 982 | length = 1; | ||
| 983 | else | ||
| 984 | length = length_byte; | ||
| 973 | idx = strp - SDATA (string) + 1; | 985 | idx = strp - SDATA (string) + 1; |
| 974 | goto subst_quote; | 986 | goto subst_quote; |
| 975 | } | 987 | } |