diff options
| author | Paul Eggert | 2012-05-26 15:27:21 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-05-26 15:27:21 -0700 |
| commit | c1892f1145dd05df037fc580acc5616f6d164238 (patch) | |
| tree | f56ded1081fc8c09076df37b41e7abe844380410 /src/coding.c | |
| parent | 38264cc938d9f2fb63f1697b4ec3dc9b86640e5f (diff) | |
| download | emacs-c1892f1145dd05df037fc580acc5616f6d164238.tar.gz emacs-c1892f1145dd05df037fc580acc5616f6d164238.zip | |
Fix coding-related core dumps with gcc -ftrapv.
The code was computing A - B, where A and B are pointers, and B is
random garbage. This can lead to core dumps on platforms that
have special pointer registers, and it also leads to core dumps on
x86-64 when compiled with gcc -ftrapv. The fix is to compute
A - B only when B is initialized properly.
* coding.c (coding_set_source, coding_set_destination): Return void.
(coding_change_source, coding_change_destinations): New functions,
with the old behaviors of coding_set_source and coding_set_destination.
All callers that need an offset changed to use these new functions.
Diffstat (limited to 'src/coding.c')
| -rw-r--r-- | src/coding.c | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/src/coding.c b/src/coding.c index 42f342c390f..17e342298b9 100644 --- a/src/coding.c +++ b/src/coding.c | |||
| @@ -847,8 +847,10 @@ static int encode_coding_ccl (struct coding_system *); | |||
| 847 | static void decode_coding_raw_text (struct coding_system *); | 847 | static void decode_coding_raw_text (struct coding_system *); |
| 848 | static int encode_coding_raw_text (struct coding_system *); | 848 | static int encode_coding_raw_text (struct coding_system *); |
| 849 | 849 | ||
| 850 | static ptrdiff_t coding_set_source (struct coding_system *); | 850 | static void coding_set_source (struct coding_system *); |
| 851 | static ptrdiff_t coding_set_destination (struct coding_system *); | 851 | static ptrdiff_t coding_change_source (struct coding_system *); |
| 852 | static void coding_set_destination (struct coding_system *); | ||
| 853 | static ptrdiff_t coding_change_destination (struct coding_system *); | ||
| 852 | static void coding_alloc_by_realloc (struct coding_system *, ptrdiff_t); | 854 | static void coding_alloc_by_realloc (struct coding_system *, ptrdiff_t); |
| 853 | static void coding_alloc_by_making_gap (struct coding_system *, | 855 | static void coding_alloc_by_making_gap (struct coding_system *, |
| 854 | ptrdiff_t, ptrdiff_t); | 856 | ptrdiff_t, ptrdiff_t); |
| @@ -927,7 +929,7 @@ record_conversion_result (struct coding_system *coding, | |||
| 927 | charset_map_loaded = 0; \ | 929 | charset_map_loaded = 0; \ |
| 928 | c = DECODE_CHAR (charset, code); \ | 930 | c = DECODE_CHAR (charset, code); \ |
| 929 | if (charset_map_loaded \ | 931 | if (charset_map_loaded \ |
| 930 | && (offset = coding_set_source (coding))) \ | 932 | && (offset = coding_change_source (coding))) \ |
| 931 | { \ | 933 | { \ |
| 932 | src += offset; \ | 934 | src += offset; \ |
| 933 | src_base += offset; \ | 935 | src_base += offset; \ |
| @@ -942,7 +944,7 @@ record_conversion_result (struct coding_system *coding, | |||
| 942 | charset_map_loaded = 0; \ | 944 | charset_map_loaded = 0; \ |
| 943 | code = ENCODE_CHAR (charset, c); \ | 945 | code = ENCODE_CHAR (charset, c); \ |
| 944 | if (charset_map_loaded \ | 946 | if (charset_map_loaded \ |
| 945 | && (offset = coding_set_destination (coding))) \ | 947 | && (offset = coding_change_destination (coding))) \ |
| 946 | { \ | 948 | { \ |
| 947 | dst += offset; \ | 949 | dst += offset; \ |
| 948 | dst_end += offset; \ | 950 | dst_end += offset; \ |
| @@ -956,7 +958,7 @@ record_conversion_result (struct coding_system *coding, | |||
| 956 | charset_map_loaded = 0; \ | 958 | charset_map_loaded = 0; \ |
| 957 | charset = char_charset (c, charset_list, code_return); \ | 959 | charset = char_charset (c, charset_list, code_return); \ |
| 958 | if (charset_map_loaded \ | 960 | if (charset_map_loaded \ |
| 959 | && (offset = coding_set_destination (coding))) \ | 961 | && (offset = coding_change_destination (coding))) \ |
| 960 | { \ | 962 | { \ |
| 961 | dst += offset; \ | 963 | dst += offset; \ |
| 962 | dst_end += offset; \ | 964 | dst_end += offset; \ |
| @@ -970,7 +972,7 @@ record_conversion_result (struct coding_system *coding, | |||
| 970 | charset_map_loaded = 0; \ | 972 | charset_map_loaded = 0; \ |
| 971 | result = CHAR_CHARSET_P (c, charset); \ | 973 | result = CHAR_CHARSET_P (c, charset); \ |
| 972 | if (charset_map_loaded \ | 974 | if (charset_map_loaded \ |
| 973 | && (offset = coding_set_destination (coding))) \ | 975 | && (offset = coding_change_destination (coding))) \ |
| 974 | { \ | 976 | { \ |
| 975 | dst += offset; \ | 977 | dst += offset; \ |
| 976 | dst_end += offset; \ | 978 | dst_end += offset; \ |
| @@ -1056,14 +1058,11 @@ record_conversion_result (struct coding_system *coding, | |||
| 1056 | | ((p)[-1] & 0x3F)))) | 1058 | | ((p)[-1] & 0x3F)))) |
| 1057 | 1059 | ||
| 1058 | 1060 | ||
| 1059 | /* Update coding->source from coding->src_object, and return how many | 1061 | /* Set coding->source from coding->src_object. */ |
| 1060 | bytes coding->source was changed. */ | ||
| 1061 | 1062 | ||
| 1062 | static ptrdiff_t | 1063 | static void |
| 1063 | coding_set_source (struct coding_system *coding) | 1064 | coding_set_source (struct coding_system *coding) |
| 1064 | { | 1065 | { |
| 1065 | const unsigned char *orig = coding->source; | ||
| 1066 | |||
| 1067 | if (BUFFERP (coding->src_object)) | 1066 | if (BUFFERP (coding->src_object)) |
| 1068 | { | 1067 | { |
| 1069 | struct buffer *buf = XBUFFER (coding->src_object); | 1068 | struct buffer *buf = XBUFFER (coding->src_object); |
| @@ -1082,18 +1081,26 @@ coding_set_source (struct coding_system *coding) | |||
| 1082 | /* Otherwise, the source is C string and is never relocated | 1081 | /* Otherwise, the source is C string and is never relocated |
| 1083 | automatically. Thus we don't have to update anything. */ | 1082 | automatically. Thus we don't have to update anything. */ |
| 1084 | } | 1083 | } |
| 1085 | return coding->source - orig; | ||
| 1086 | } | 1084 | } |
| 1087 | 1085 | ||
| 1088 | 1086 | ||
| 1089 | /* Update coding->destination from coding->dst_object, and return how | 1087 | /* Set coding->source from coding->src_object, and return how many |
| 1090 | many bytes coding->destination was changed. */ | 1088 | bytes coding->source was changed. */ |
| 1091 | 1089 | ||
| 1092 | static ptrdiff_t | 1090 | static ptrdiff_t |
| 1093 | coding_set_destination (struct coding_system *coding) | 1091 | coding_change_source (struct coding_system *coding) |
| 1094 | { | 1092 | { |
| 1095 | const unsigned char *orig = coding->destination; | 1093 | const unsigned char *orig = coding->source; |
| 1094 | coding_set_source (coding); | ||
| 1095 | return coding->source - orig; | ||
| 1096 | } | ||
| 1096 | 1097 | ||
| 1098 | |||
| 1099 | /* Set coding->destination from coding->dst_object. */ | ||
| 1100 | |||
| 1101 | static void | ||
| 1102 | coding_set_destination (struct coding_system *coding) | ||
| 1103 | { | ||
| 1097 | if (BUFFERP (coding->dst_object)) | 1104 | if (BUFFERP (coding->dst_object)) |
| 1098 | { | 1105 | { |
| 1099 | if (BUFFERP (coding->src_object) && coding->src_pos < 0) | 1106 | if (BUFFERP (coding->src_object) && coding->src_pos < 0) |
| @@ -1118,6 +1125,17 @@ coding_set_destination (struct coding_system *coding) | |||
| 1118 | /* Otherwise, the destination is C string and is never relocated | 1125 | /* Otherwise, the destination is C string and is never relocated |
| 1119 | automatically. Thus we don't have to update anything. */ | 1126 | automatically. Thus we don't have to update anything. */ |
| 1120 | } | 1127 | } |
| 1128 | } | ||
| 1129 | |||
| 1130 | |||
| 1131 | /* Set coding->destination from coding->dst_object, and return how | ||
| 1132 | many bytes coding->destination was changed. */ | ||
| 1133 | |||
| 1134 | static ptrdiff_t | ||
| 1135 | coding_change_destination (struct coding_system *coding) | ||
| 1136 | { | ||
| 1137 | const unsigned char *orig = coding->destination; | ||
| 1138 | coding_set_destination (coding); | ||
| 1121 | return coding->destination - orig; | 1139 | return coding->destination - orig; |
| 1122 | } | 1140 | } |
| 1123 | 1141 | ||
| @@ -4452,7 +4470,7 @@ encode_coding_iso_2022 (struct coding_system *coding) | |||
| 4452 | nbytes = encode_designation_at_bol (coding, charbuf, charbuf_end, | 4470 | nbytes = encode_designation_at_bol (coding, charbuf, charbuf_end, |
| 4453 | desig_buf); | 4471 | desig_buf); |
| 4454 | if (charset_map_loaded | 4472 | if (charset_map_loaded |
| 4455 | && (offset = coding_set_destination (coding))) | 4473 | && (offset = coding_change_destination (coding))) |
| 4456 | { | 4474 | { |
| 4457 | dst += offset; | 4475 | dst += offset; |
| 4458 | dst_end += offset; | 4476 | dst_end += offset; |