aboutsummaryrefslogtreecommitdiffstats
path: root/src/coding.c
diff options
context:
space:
mode:
authorPaul Eggert2012-05-26 15:27:21 -0700
committerPaul Eggert2012-05-26 15:27:21 -0700
commitc1892f1145dd05df037fc580acc5616f6d164238 (patch)
treef56ded1081fc8c09076df37b41e7abe844380410 /src/coding.c
parent38264cc938d9f2fb63f1697b4ec3dc9b86640e5f (diff)
downloademacs-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.c52
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 *);
847static void decode_coding_raw_text (struct coding_system *); 847static void decode_coding_raw_text (struct coding_system *);
848static int encode_coding_raw_text (struct coding_system *); 848static int encode_coding_raw_text (struct coding_system *);
849 849
850static ptrdiff_t coding_set_source (struct coding_system *); 850static void coding_set_source (struct coding_system *);
851static ptrdiff_t coding_set_destination (struct coding_system *); 851static ptrdiff_t coding_change_source (struct coding_system *);
852static void coding_set_destination (struct coding_system *);
853static ptrdiff_t coding_change_destination (struct coding_system *);
852static void coding_alloc_by_realloc (struct coding_system *, ptrdiff_t); 854static void coding_alloc_by_realloc (struct coding_system *, ptrdiff_t);
853static void coding_alloc_by_making_gap (struct coding_system *, 855static 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
1062static ptrdiff_t 1063static void
1063coding_set_source (struct coding_system *coding) 1064coding_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
1092static ptrdiff_t 1090static ptrdiff_t
1093coding_set_destination (struct coding_system *coding) 1091coding_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
1101static void
1102coding_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
1134static ptrdiff_t
1135coding_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;