aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-05-27 12:37:32 -0700
committerPaul Eggert2011-05-27 12:37:32 -0700
commit0f6990a78ae5016d8ae73253cdb4739adf0197e7 (patch)
tree78c7860e14d7cf6bc73526174493a02e606dfc13 /src
parentfb1ac845caea7da6ba98b93c3d67fa67c651b8ef (diff)
parentb57f7e0a357aacf98ec5be826f7227f37e9806b8 (diff)
downloademacs-0f6990a78ae5016d8ae73253cdb4739adf0197e7.tar.gz
emacs-0f6990a78ae5016d8ae73253cdb4739adf0197e7.zip
Merge: Integer overflow fixes.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog82
-rw-r--r--src/alloc.c2
-rw-r--r--src/ccl.c237
-rw-r--r--src/character.c9
-rw-r--r--src/character.h2
-rw-r--r--src/data.c41
-rw-r--r--src/dbusbind.c94
-rw-r--r--src/editfns.c911
-rw-r--r--src/fns.c2
-rw-r--r--src/insdel.c31
-rw-r--r--src/lisp.h6
-rw-r--r--src/mem-limits.h5
-rw-r--r--src/print.c2
13 files changed, 855 insertions, 569 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 1ffeba88607..d45543c8d36 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,87 @@
12011-05-27 Paul Eggert <eggert@cs.ucla.edu> 12011-05-27 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Integer overflow fixes.
4
5 * dbusbind.c: Serial number integer overflow fixes.
6 (CHECK_DBUS_SERIAL_GET_SERIAL): New macro.
7 (Fdbus_call_method_asynchronously, xd_read_message_1): Use a float
8 to hold a serial number that is too large for a fixnum.
9 (Fdbus_method_return_internal, Fdbus_method_error_internal):
10 Check for serial numbers out of range. Decode any serial number
11 that was so large that it became a float. (Bug#8722)
12
13 * dbusbind.c: Use XFASTINT rather than XUINT, and check for nonneg.
14 (Fdbus_call_method, Fdbus_call_method_asynchronously):
15 Use XFASTINT rather than XUINT when numbers are nonnegative.
16 (xd_append_arg, Fdbus_method_return_internal):
17 (Fdbus_method_error_internal): Likewise. Also, for unsigned
18 arguments, check that Lisp number is nonnegative, rather than
19 silently wrapping negative numbers around. (Bug#8722)
20 (xd_read_message_1): Don't assume dbus_uint32_t can fit in int.
21 (Bug#8722)
22
23 * data.c (arith_driver, Flsh): Avoid unnecessary casts to EMACS_UINT.
24
25 * ccl.c (ccl_driver): Redo slightly to avoid the need for 'unsigned'.
26
27 ccl: add integer overflow checks
28 * ccl.c (CCL_CODE_MAX, GET_CCL_RANGE, GET_CCL_CODE, GET_CCL_INT):
29 (IN_INT_RANGE): New macros.
30 (ccl_driver): Use them to check for integer overflow when
31 decoding a CCL program. Many of the new checks are whether XINT (x)
32 fits in int; it doesn't always, on 64-bit hosts. The new version
33 doesn't catch all possible integer overflows, but it's an
34 improvement. (Bug#8719)
35
36 * alloc.c (make_event_array): Use XINT, not XUINT.
37 There's no need for unsigned here.
38
39 * mem-limits.h (EXCEEDS_LISP_PTR) [!USE_LSB_TAG]: EMACS_UINT -> uintptr_t
40 This follows up to the 2011-05-06 change that substituted uintptr_t
41 for EMACS_INT. This case wasn't caught back then.
42
43 Rework Fformat to avoid integer overflow issues.
44 * editfns.c: Include <float.h> unconditionally, as it's everywhere
45 now (part of C89). Include <verify.h>.
46 (MAX_10_EXP, CONVERTED_BYTE_SIZE): Remove; no longer needed.
47 (pWIDE, pWIDElen, signed_wide, unsigned_wide): New defns.
48 (Fformat): Avoid the prepass trying to compute sizes; it was only
49 approximate and thus did not catch overflow reliably. Instead, walk
50 through the format just once, formatting and computing sizes as we go,
51 checking for integer overflow at every step, and allocating a larger
52 buffer as needed. Keep track separately whether the format is
53 multibyte. Keep only the most-recently calculated precision, rather
54 than them all. Record whether each argument has been converted to
55 string. Use EMACS_INT, not int, for byte and char and arg counts.
56 Support field widths and precisions larger than INT_MAX. Avoid
57 sprintf's undefined behavior with conversion specifications such as %#d
58 and %.0c. Fix bug with strchr succeeding on '\0' when looking for
59 flags. Fix bug with (format "%c" 256.0). Avoid integer overflow when
60 formatting out-of-range floating point numbers with int
61 formats. (Bug#8668)
62
63 * lisp.h (FIXNUM_OVERFLOW_P): Work even if arg is a NaN.
64
65 * data.c: Avoid integer truncation in expressions involving floats.
66 * data.c: Include <intprops.h>.
67 (arith_driver): When there's an integer overflow in an expression
68 involving floating point, convert the integers to floating point
69 so that the resulting value does not suffer from catastrophic
70 integer truncation. For example, on a 64-bit host (* 4
71 most-negative-fixnum 0.5) should yield about -4.6e+18, not zero.
72 Do not rely on undefined behavior after integer overflow.
73
74 merge count_size_as_multibyte, parse_str_to_multibyte
75 * character.c, character.h (count_size_as_multibyte):
76 Renamed from parse_str_to_multibyte; all uses changed.
77 Check for integer overflow.
78 * insdel.c, lisp.h (count_size_as_multibyte): Remove,
79 since it's now a duplicate of the other. This is more of
80 a character than a buffer op, so better that it's in character.c.
81 * fns.c, print.c: Adjust to above changes.
82
832011-05-27 Paul Eggert <eggert@cs.ucla.edu>
84
3 * xselect.c: Fix minor problems prompted by GCC 4.6.0 warnings. 85 * xselect.c: Fix minor problems prompted by GCC 4.6.0 warnings.
4 (x_handle_selection_request, frame_for_x_selection): Remove unused vars. 86 (x_handle_selection_request, frame_for_x_selection): Remove unused vars.
5 (x_clipboard_manager_save): Now static. 87 (x_clipboard_manager_save): Now static.
diff --git a/src/alloc.c b/src/alloc.c
index 71ab54bcab5..3f7bed571c7 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3244,7 +3244,7 @@ make_event_array (register int nargs, Lisp_Object *args)
3244 are characters that are in 0...127, 3244 are characters that are in 0...127,
3245 after discarding the meta bit and all the bits above it. */ 3245 after discarding the meta bit and all the bits above it. */
3246 if (!INTEGERP (args[i]) 3246 if (!INTEGERP (args[i])
3247 || (XUINT (args[i]) & ~(-CHAR_META)) >= 0200) 3247 || (XINT (args[i]) & ~(-CHAR_META)) >= 0200)
3248 return Fvector (nargs, args); 3248 return Fvector (nargs, args);
3249 3249
3250 /* Since the loop exited, we know that all the things in it are 3250 /* Since the loop exited, we know that all the things in it are
diff --git a/src/ccl.c b/src/ccl.c
index 83afd7bc800..98b060522a4 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -98,6 +98,8 @@ static Lisp_Object Vccl_program_table;
98 and `rrr' are CCL register number, `XXXXX' is one of the following 98 and `rrr' are CCL register number, `XXXXX' is one of the following
99 CCL commands. */ 99 CCL commands. */
100 100
101#define CCL_CODE_MAX ((1 << (28 - 1)) - 1)
102
101/* CCL commands 103/* CCL commands
102 104
103 Each comment fields shows one or more lines for command syntax and 105 Each comment fields shows one or more lines for command syntax and
@@ -742,6 +744,24 @@ while(0)
742 744
743#endif 745#endif
744 746
747#define GET_CCL_RANGE(var, ccl_prog, ic, lo, hi) \
748 do \
749 { \
750 EMACS_INT prog_word = XINT ((ccl_prog)[ic]); \
751 if (! ((lo) <= prog_word && prog_word <= (hi))) \
752 CCL_INVALID_CMD; \
753 (var) = prog_word; \
754 } \
755 while (0)
756
757#define GET_CCL_CODE(code, ccl_prog, ic) \
758 GET_CCL_RANGE (code, ccl_prog, ic, 0, CCL_CODE_MAX)
759
760#define GET_CCL_INT(var, ccl_prog, ic) \
761 GET_CCL_RANGE (var, ccl_prog, ic, INT_MIN, INT_MAX)
762
763#define IN_INT_RANGE(val) (INT_MIN <= (val) && (val) <= INT_MAX)
764
745/* Encode one character CH to multibyte form and write to the current 765/* Encode one character CH to multibyte form and write to the current
746 output buffer. If CH is less than 256, CH is written as is. */ 766 output buffer. If CH is less than 256, CH is written as is. */
747#define CCL_WRITE_CHAR(ch) \ 767#define CCL_WRITE_CHAR(ch) \
@@ -899,7 +919,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
899 } 919 }
900 920
901 this_ic = ic; 921 this_ic = ic;
902 code = XINT (ccl_prog[ic]); ic++; 922 GET_CCL_CODE (code, ccl_prog, ic++);
903 field1 = code >> 8; 923 field1 = code >> 8;
904 field2 = (code & 0xFF) >> 5; 924 field2 = (code & 0xFF) >> 5;
905 925
@@ -920,15 +940,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
920 break; 940 break;
921 941
922 case CCL_SetConst: /* 00000000000000000000rrrXXXXX */ 942 case CCL_SetConst: /* 00000000000000000000rrrXXXXX */
923 reg[rrr] = XINT (ccl_prog[ic]); 943 GET_CCL_INT (reg[rrr], ccl_prog, ic++);
924 ic++;
925 break; 944 break;
926 945
927 case CCL_SetArray: /* CCCCCCCCCCCCCCCCCCCCRRRrrrXXXXX */ 946 case CCL_SetArray: /* CCCCCCCCCCCCCCCCCCCCRRRrrrXXXXX */
928 i = reg[RRR]; 947 i = reg[RRR];
929 j = field1 >> 3; 948 j = field1 >> 3;
930 if ((unsigned int) i < j) 949 if (0 <= i && i < j)
931 reg[rrr] = XINT (ccl_prog[ic + i]); 950 GET_CCL_INT (reg[rrr], ccl_prog, ic + i);
932 ic += j; 951 ic += j;
933 break; 952 break;
934 953
@@ -956,13 +975,13 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
956 break; 975 break;
957 976
958 case CCL_WriteConstJump: /* A--D--D--R--E--S--S-000XXXXX */ 977 case CCL_WriteConstJump: /* A--D--D--R--E--S--S-000XXXXX */
959 i = XINT (ccl_prog[ic]); 978 GET_CCL_INT (i, ccl_prog, ic);
960 CCL_WRITE_CHAR (i); 979 CCL_WRITE_CHAR (i);
961 ic += ADDR; 980 ic += ADDR;
962 break; 981 break;
963 982
964 case CCL_WriteConstReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ 983 case CCL_WriteConstReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */
965 i = XINT (ccl_prog[ic]); 984 GET_CCL_INT (i, ccl_prog, ic);
966 CCL_WRITE_CHAR (i); 985 CCL_WRITE_CHAR (i);
967 ic++; 986 ic++;
968 CCL_READ_CHAR (reg[rrr]); 987 CCL_READ_CHAR (reg[rrr]);
@@ -970,18 +989,17 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
970 break; 989 break;
971 990
972 case CCL_WriteStringJump: /* A--D--D--R--E--S--S-000XXXXX */ 991 case CCL_WriteStringJump: /* A--D--D--R--E--S--S-000XXXXX */
973 j = XINT (ccl_prog[ic]); 992 GET_CCL_INT (j, ccl_prog, ic++);
974 ic++;
975 CCL_WRITE_STRING (j); 993 CCL_WRITE_STRING (j);
976 ic += ADDR - 1; 994 ic += ADDR - 1;
977 break; 995 break;
978 996
979 case CCL_WriteArrayReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ 997 case CCL_WriteArrayReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */
980 i = reg[rrr]; 998 i = reg[rrr];
981 j = XINT (ccl_prog[ic]); 999 GET_CCL_INT (j, ccl_prog, ic);
982 if ((unsigned int) i < j) 1000 if (0 <= i && i < j)
983 { 1001 {
984 i = XINT (ccl_prog[ic + 1 + i]); 1002 GET_CCL_INT (i, ccl_prog, ic + 1 + i);
985 CCL_WRITE_CHAR (i); 1003 CCL_WRITE_CHAR (i);
986 } 1004 }
987 ic += j + 2; 1005 ic += j + 2;
@@ -998,10 +1016,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
998 CCL_READ_CHAR (reg[rrr]); 1016 CCL_READ_CHAR (reg[rrr]);
999 /* fall through ... */ 1017 /* fall through ... */
1000 case CCL_Branch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ 1018 case CCL_Branch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */
1001 if ((unsigned int) reg[rrr] < field1) 1019 {
1002 ic += XINT (ccl_prog[ic + reg[rrr]]); 1020 int incr;
1003 else 1021 GET_CCL_INT (incr, ccl_prog,
1004 ic += XINT (ccl_prog[ic + field1]); 1022 ic + (0 <= reg[rrr] && reg[rrr] < field1
1023 ? reg[rrr]
1024 : field1));
1025 ic += incr;
1026 }
1005 break; 1027 break;
1006 1028
1007 case CCL_ReadRegister: /* CCCCCCCCCCCCCCCCCCCCrrXXXXX */ 1029 case CCL_ReadRegister: /* CCCCCCCCCCCCCCCCCCCCrrXXXXX */
@@ -1009,7 +1031,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1009 { 1031 {
1010 CCL_READ_CHAR (reg[rrr]); 1032 CCL_READ_CHAR (reg[rrr]);
1011 if (!field1) break; 1033 if (!field1) break;
1012 code = XINT (ccl_prog[ic]); ic++; 1034 GET_CCL_CODE (code, ccl_prog, ic++);
1013 field1 = code >> 8; 1035 field1 = code >> 8;
1014 field2 = (code & 0xFF) >> 5; 1036 field2 = (code & 0xFF) >> 5;
1015 } 1037 }
@@ -1018,7 +1040,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1018 case CCL_WriteExprConst: /* 1:00000OPERATION000RRR000XXXXX */ 1040 case CCL_WriteExprConst: /* 1:00000OPERATION000RRR000XXXXX */
1019 rrr = 7; 1041 rrr = 7;
1020 i = reg[RRR]; 1042 i = reg[RRR];
1021 j = XINT (ccl_prog[ic]); 1043 GET_CCL_INT (j, ccl_prog, ic);
1022 op = field1 >> 6; 1044 op = field1 >> 6;
1023 jump_address = ic + 1; 1045 jump_address = ic + 1;
1024 goto ccl_set_expr; 1046 goto ccl_set_expr;
@@ -1029,7 +1051,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1029 i = reg[rrr]; 1051 i = reg[rrr];
1030 CCL_WRITE_CHAR (i); 1052 CCL_WRITE_CHAR (i);
1031 if (!field1) break; 1053 if (!field1) break;
1032 code = XINT (ccl_prog[ic]); ic++; 1054 GET_CCL_CODE (code, ccl_prog, ic++);
1033 field1 = code >> 8; 1055 field1 = code >> 8;
1034 field2 = (code & 0xFF) >> 5; 1056 field2 = (code & 0xFF) >> 5;
1035 } 1057 }
@@ -1051,10 +1073,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1051 /* If FFF is nonzero, the CCL program ID is in the 1073 /* If FFF is nonzero, the CCL program ID is in the
1052 following code. */ 1074 following code. */
1053 if (rrr) 1075 if (rrr)
1054 { 1076 GET_CCL_INT (prog_id, ccl_prog, ic++);
1055 prog_id = XINT (ccl_prog[ic]);
1056 ic++;
1057 }
1058 else 1077 else
1059 prog_id = field1; 1078 prog_id = field1;
1060 1079
@@ -1095,9 +1114,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1095 1114
1096 case CCL_WriteArray: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ 1115 case CCL_WriteArray: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */
1097 i = reg[rrr]; 1116 i = reg[rrr];
1098 if ((unsigned int) i < field1) 1117 if (0 <= i && i < field1)
1099 { 1118 {
1100 j = XINT (ccl_prog[ic + i]); 1119 GET_CCL_INT (j, ccl_prog, ic + i);
1101 CCL_WRITE_CHAR (j); 1120 CCL_WRITE_CHAR (j);
1102 } 1121 }
1103 ic += field1; 1122 ic += field1;
@@ -1122,8 +1141,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1122 CCL_SUCCESS; 1141 CCL_SUCCESS;
1123 1142
1124 case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */ 1143 case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */
1125 i = XINT (ccl_prog[ic]); 1144 GET_CCL_INT (i, ccl_prog, ic++);
1126 ic++;
1127 op = field1 >> 6; 1145 op = field1 >> 6;
1128 goto ccl_expr_self; 1146 goto ccl_expr_self;
1129 1147
@@ -1159,9 +1177,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1159 1177
1160 case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */ 1178 case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */
1161 i = reg[RRR]; 1179 i = reg[RRR];
1162 j = XINT (ccl_prog[ic]); 1180 GET_CCL_INT (j, ccl_prog, ic++);
1163 op = field1 >> 6; 1181 op = field1 >> 6;
1164 jump_address = ++ic; 1182 jump_address = ic;
1165 goto ccl_set_expr; 1183 goto ccl_set_expr;
1166 1184
1167 case CCL_SetExprReg: /* 00000OPERATIONRrrRRRrrrXXXXX */ 1185 case CCL_SetExprReg: /* 00000OPERATIONRrrRRRrrrXXXXX */
@@ -1175,10 +1193,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1175 CCL_READ_CHAR (reg[rrr]); 1193 CCL_READ_CHAR (reg[rrr]);
1176 case CCL_JumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */ 1194 case CCL_JumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */
1177 i = reg[rrr]; 1195 i = reg[rrr];
1178 op = XINT (ccl_prog[ic]); 1196 jump_address = ic + ADDR;
1179 jump_address = ic++ + ADDR; 1197 GET_CCL_INT (op, ccl_prog, ic++);
1180 j = XINT (ccl_prog[ic]); 1198 GET_CCL_INT (j, ccl_prog, ic++);
1181 ic++;
1182 rrr = 7; 1199 rrr = 7;
1183 goto ccl_set_expr; 1200 goto ccl_set_expr;
1184 1201
@@ -1186,10 +1203,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1186 CCL_READ_CHAR (reg[rrr]); 1203 CCL_READ_CHAR (reg[rrr]);
1187 case CCL_JumpCondExprReg: 1204 case CCL_JumpCondExprReg:
1188 i = reg[rrr]; 1205 i = reg[rrr];
1189 op = XINT (ccl_prog[ic]); 1206 jump_address = ic + ADDR;
1190 jump_address = ic++ + ADDR; 1207 GET_CCL_INT (op, ccl_prog, ic++);
1191 j = reg[XINT (ccl_prog[ic])]; 1208 GET_CCL_RANGE (j, ccl_prog, ic++, 0, 7);
1192 ic++; 1209 j = reg[j];
1193 rrr = 7; 1210 rrr = 7;
1194 1211
1195 ccl_set_expr: 1212 ccl_set_expr:
@@ -1267,18 +1284,27 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1267 break; 1284 break;
1268 1285
1269 case CCL_TranslateCharacterConstTbl: 1286 case CCL_TranslateCharacterConstTbl:
1270 op = XINT (ccl_prog[ic]); /* table */ 1287 {
1271 ic++; 1288 EMACS_INT eop;
1272 i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); 1289 GET_CCL_RANGE (eop, ccl_prog, ic++, 0,
1273 op = translate_char (GET_TRANSLATION_TABLE (op), i); 1290 (VECTORP (Vtranslation_table_vector)
1274 CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]); 1291 ? ASIZE (Vtranslation_table_vector)
1292 : -1));
1293 i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
1294 op = translate_char (GET_TRANSLATION_TABLE (eop), i);
1295 CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]);
1296 }
1275 break; 1297 break;
1276 1298
1277 case CCL_LookupIntConstTbl: 1299 case CCL_LookupIntConstTbl:
1278 op = XINT (ccl_prog[ic]); /* table */
1279 ic++;
1280 { 1300 {
1281 struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); 1301 EMACS_INT eop;
1302 struct Lisp_Hash_Table *h;
1303 GET_CCL_RANGE (eop, ccl_prog, ic++, 0,
1304 (VECTORP (Vtranslation_hash_table_vector)
1305 ? ASIZE (Vtranslation_hash_table_vector)
1306 : -1));
1307 h = GET_HASH_TABLE (eop);
1282 1308
1283 op = hash_lookup (h, make_number (reg[RRR]), NULL); 1309 op = hash_lookup (h, make_number (reg[RRR]), NULL);
1284 if (op >= 0) 1310 if (op >= 0)
@@ -1297,18 +1323,22 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1297 break; 1323 break;
1298 1324
1299 case CCL_LookupCharConstTbl: 1325 case CCL_LookupCharConstTbl:
1300 op = XINT (ccl_prog[ic]); /* table */
1301 ic++;
1302 i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
1303 { 1326 {
1304 struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); 1327 EMACS_INT eop;
1328 struct Lisp_Hash_Table *h;
1329 GET_CCL_RANGE (eop, ccl_prog, ic++, 0,
1330 (VECTORP (Vtranslation_hash_table_vector)
1331 ? ASIZE (Vtranslation_hash_table_vector)
1332 : -1));
1333 i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
1334 h = GET_HASH_TABLE (eop);
1305 1335
1306 op = hash_lookup (h, make_number (i), NULL); 1336 op = hash_lookup (h, make_number (i), NULL);
1307 if (op >= 0) 1337 if (op >= 0)
1308 { 1338 {
1309 Lisp_Object opl; 1339 Lisp_Object opl;
1310 opl = HASH_VALUE (h, op); 1340 opl = HASH_VALUE (h, op);
1311 if (!INTEGERP (opl)) 1341 if (! (INTEGERP (opl) && IN_INT_RANGE (XINT (opl))))
1312 CCL_INVALID_CMD; 1342 CCL_INVALID_CMD;
1313 reg[RRR] = XINT (opl); 1343 reg[RRR] = XINT (opl);
1314 reg[7] = 1; /* r7 true for success */ 1344 reg[7] = 1; /* r7 true for success */
@@ -1321,9 +1351,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1321 case CCL_IterateMultipleMap: 1351 case CCL_IterateMultipleMap:
1322 { 1352 {
1323 Lisp_Object map, content, attrib, value; 1353 Lisp_Object map, content, attrib, value;
1324 int point, size, fin_ic; 1354 EMACS_INT point, size;
1355 int fin_ic;
1325 1356
1326 j = XINT (ccl_prog[ic++]); /* number of maps. */ 1357 GET_CCL_INT (j, ccl_prog, ic++); /* number of maps. */
1327 fin_ic = ic + j; 1358 fin_ic = ic + j;
1328 op = reg[rrr]; 1359 op = reg[rrr];
1329 if ((j > reg[RRR]) && (j >= 0)) 1360 if ((j > reg[RRR]) && (j >= 0))
@@ -1343,7 +1374,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1343 1374
1344 size = ASIZE (Vcode_conversion_map_vector); 1375 size = ASIZE (Vcode_conversion_map_vector);
1345 point = XINT (ccl_prog[ic++]); 1376 point = XINT (ccl_prog[ic++]);
1346 if (point >= size) continue; 1377 if (! (0 <= point && point < size)) continue;
1347 map = AREF (Vcode_conversion_map_vector, point); 1378 map = AREF (Vcode_conversion_map_vector, point);
1348 1379
1349 /* Check map validity. */ 1380 /* Check map validity. */
@@ -1358,18 +1389,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1358 /* check map type, 1389 /* check map type,
1359 [STARTPOINT VAL1 VAL2 ...] or 1390 [STARTPOINT VAL1 VAL2 ...] or
1360 [t ELEMENT STARTPOINT ENDPOINT] */ 1391 [t ELEMENT STARTPOINT ENDPOINT] */
1361 if (NUMBERP (content)) 1392 if (INTEGERP (content))
1362 { 1393 {
1363 point = XUINT (content); 1394 point = XINT (content);
1364 point = op - point + 1; 1395 if (!(point <= op && op - point + 1 < size)) continue;
1365 if (!((point >= 1) && (point < size))) continue; 1396 content = AREF (map, op - point + 1);
1366 content = AREF (map, point);
1367 } 1397 }
1368 else if (EQ (content, Qt)) 1398 else if (EQ (content, Qt))
1369 { 1399 {
1370 if (size != 4) continue; 1400 if (size != 4) continue;
1371 if ((op >= XUINT (AREF (map, 2))) 1401 if (INTEGERP (AREF (map, 2))
1372 && (op < XUINT (AREF (map, 3)))) 1402 && XINT (AREF (map, 2)) <= op
1403 && INTEGERP (AREF (map, 3))
1404 && op < XINT (AREF (map, 3)))
1373 content = AREF (map, 1); 1405 content = AREF (map, 1);
1374 else 1406 else
1375 continue; 1407 continue;
@@ -1379,7 +1411,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1379 1411
1380 if (NILP (content)) 1412 if (NILP (content))
1381 continue; 1413 continue;
1382 else if (NUMBERP (content)) 1414 else if (INTEGERP (content) && IN_INT_RANGE (XINT (content)))
1383 { 1415 {
1384 reg[RRR] = i; 1416 reg[RRR] = i;
1385 reg[rrr] = XINT(content); 1417 reg[rrr] = XINT(content);
@@ -1394,10 +1426,11 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1394 { 1426 {
1395 attrib = XCAR (content); 1427 attrib = XCAR (content);
1396 value = XCDR (content); 1428 value = XCDR (content);
1397 if (!NUMBERP (attrib) || !NUMBERP (value)) 1429 if (! (INTEGERP (attrib) && INTEGERP (value)
1430 && IN_INT_RANGE (XINT (value))))
1398 continue; 1431 continue;
1399 reg[RRR] = i; 1432 reg[RRR] = i;
1400 reg[rrr] = XUINT (value); 1433 reg[rrr] = XINT (value);
1401 break; 1434 break;
1402 } 1435 }
1403 else if (SYMBOLP (content)) 1436 else if (SYMBOLP (content))
@@ -1432,8 +1465,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1432 mapping_stack_pointer = mapping_stack; 1465 mapping_stack_pointer = mapping_stack;
1433 stack_idx_of_map_multiple = 0; 1466 stack_idx_of_map_multiple = 0;
1434 1467
1435 map_set_rest_length = 1468 /* Get number of maps and separators. */
1436 XINT (ccl_prog[ic++]); /* number of maps and separators. */ 1469 GET_CCL_INT (map_set_rest_length, ccl_prog, ic++);
1470
1437 fin_ic = ic + map_set_rest_length; 1471 fin_ic = ic + map_set_rest_length;
1438 op = reg[rrr]; 1472 op = reg[rrr];
1439 1473
@@ -1501,7 +1535,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1501 do { 1535 do {
1502 for (;map_set_rest_length > 0;i++, ic++, map_set_rest_length--) 1536 for (;map_set_rest_length > 0;i++, ic++, map_set_rest_length--)
1503 { 1537 {
1504 point = XINT(ccl_prog[ic]); 1538 GET_CCL_INT (point, ccl_prog, ic);
1505 if (point < 0) 1539 if (point < 0)
1506 { 1540 {
1507 /* +1 is for including separator. */ 1541 /* +1 is for including separator. */
@@ -1531,18 +1565,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1531 /* check map type, 1565 /* check map type,
1532 [STARTPOINT VAL1 VAL2 ...] or 1566 [STARTPOINT VAL1 VAL2 ...] or
1533 [t ELEMENT STARTPOINT ENDPOINT] */ 1567 [t ELEMENT STARTPOINT ENDPOINT] */
1534 if (NUMBERP (content)) 1568 if (INTEGERP (content))
1535 { 1569 {
1536 point = XUINT (content); 1570 point = XINT (content);
1537 point = op - point + 1; 1571 if (!(point <= op && op - point + 1 < size)) continue;
1538 if (!((point >= 1) && (point < size))) continue; 1572 content = AREF (map, op - point + 1);
1539 content = AREF (map, point);
1540 } 1573 }
1541 else if (EQ (content, Qt)) 1574 else if (EQ (content, Qt))
1542 { 1575 {
1543 if (size != 4) continue; 1576 if (size != 4) continue;
1544 if ((op >= XUINT (AREF (map, 2))) && 1577 if (INTEGERP (AREF (map, 2))
1545 (op < XUINT (AREF (map, 3)))) 1578 && XINT (AREF (map, 2)) <= op
1579 && INTEGERP (AREF (map, 3))
1580 && op < XINT (AREF (map, 3)))
1546 content = AREF (map, 1); 1581 content = AREF (map, 1);
1547 else 1582 else
1548 continue; 1583 continue;
@@ -1554,7 +1589,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1554 continue; 1589 continue;
1555 1590
1556 reg[RRR] = i; 1591 reg[RRR] = i;
1557 if (NUMBERP (content)) 1592 if (INTEGERP (content) && IN_INT_RANGE (XINT (content)))
1558 { 1593 {
1559 op = XINT (content); 1594 op = XINT (content);
1560 i += map_set_rest_length - 1; 1595 i += map_set_rest_length - 1;
@@ -1566,9 +1601,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1566 { 1601 {
1567 attrib = XCAR (content); 1602 attrib = XCAR (content);
1568 value = XCDR (content); 1603 value = XCDR (content);
1569 if (!NUMBERP (attrib) || !NUMBERP (value)) 1604 if (! (INTEGERP (attrib) && INTEGERP (value)
1605 && IN_INT_RANGE (XINT (value))))
1570 continue; 1606 continue;
1571 op = XUINT (value); 1607 op = XINT (value);
1572 i += map_set_rest_length - 1; 1608 i += map_set_rest_length - 1;
1573 ic += map_set_rest_length - 1; 1609 ic += map_set_rest_length - 1;
1574 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]); 1610 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
@@ -1613,7 +1649,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1613 case CCL_MapSingle: 1649 case CCL_MapSingle:
1614 { 1650 {
1615 Lisp_Object map, attrib, value, content; 1651 Lisp_Object map, attrib, value, content;
1616 int size, point; 1652 int point;
1617 j = XINT (ccl_prog[ic++]); /* map_id */ 1653 j = XINT (ccl_prog[ic++]); /* map_id */
1618 op = reg[rrr]; 1654 op = reg[rrr];
1619 if (j >= ASIZE (Vcode_conversion_map_vector)) 1655 if (j >= ASIZE (Vcode_conversion_map_vector))
@@ -1628,41 +1664,36 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1628 break; 1664 break;
1629 } 1665 }
1630 map = XCDR (map); 1666 map = XCDR (map);
1631 if (!VECTORP (map)) 1667 if (! (VECTORP (map)
1668 && INTEGERP (AREF (map, 0))
1669 && XINT (AREF (map, 0)) <= op
1670 && op - XINT (AREF (map, 0)) + 1 < ASIZE (map)))
1632 { 1671 {
1633 reg[RRR] = -1; 1672 reg[RRR] = -1;
1634 break; 1673 break;
1635 } 1674 }
1636 size = ASIZE (map); 1675 point = XINT (AREF (map, 0));
1637 point = XUINT (AREF (map, 0));
1638 point = op - point + 1; 1676 point = op - point + 1;
1639 reg[RRR] = 0; 1677 reg[RRR] = 0;
1640 if ((size <= 1) || 1678 content = AREF (map, point);
1641 (!((point >= 1) && (point < size)))) 1679 if (NILP (content))
1642 reg[RRR] = -1; 1680 reg[RRR] = -1;
1643 else 1681 else if (INTEGERP (content))
1682 reg[rrr] = XINT (content);
1683 else if (EQ (content, Qt));
1684 else if (CONSP (content))
1644 { 1685 {
1645 reg[RRR] = 0; 1686 attrib = XCAR (content);
1646 content = AREF (map, point); 1687 value = XCDR (content);
1647 if (NILP (content)) 1688 if (!INTEGERP (attrib) || !INTEGERP (value))
1648 reg[RRR] = -1; 1689 continue;
1649 else if (NUMBERP (content)) 1690 reg[rrr] = XINT(value);
1650 reg[rrr] = XINT (content); 1691 break;
1651 else if (EQ (content, Qt));
1652 else if (CONSP (content))
1653 {
1654 attrib = XCAR (content);
1655 value = XCDR (content);
1656 if (!NUMBERP (attrib) || !NUMBERP (value))
1657 continue;
1658 reg[rrr] = XUINT(value);
1659 break;
1660 }
1661 else if (SYMBOLP (content))
1662 CCL_CALL_FOR_MAP_INSTRUCTION (content, ic);
1663 else
1664 reg[RRR] = -1;
1665 } 1692 }
1693 else if (SYMBOLP (content))
1694 CCL_CALL_FOR_MAP_INSTRUCTION (content, ic);
1695 else
1696 reg[RRR] = -1;
1666 } 1697 }
1667 break; 1698 break;
1668 1699
diff --git a/src/character.c b/src/character.c
index b9595f97ec7..34e69da9cc5 100644
--- a/src/character.c
+++ b/src/character.c
@@ -672,13 +672,18 @@ str_as_multibyte (unsigned char *str, EMACS_INT len, EMACS_INT nbytes,
672 `str_to_multibyte'. */ 672 `str_to_multibyte'. */
673 673
674EMACS_INT 674EMACS_INT
675parse_str_to_multibyte (const unsigned char *str, EMACS_INT len) 675count_size_as_multibyte (const unsigned char *str, EMACS_INT len)
676{ 676{
677 const unsigned char *endp = str + len; 677 const unsigned char *endp = str + len;
678 EMACS_INT bytes; 678 EMACS_INT bytes;
679 679
680 for (bytes = 0; str < endp; str++) 680 for (bytes = 0; str < endp; str++)
681 bytes += (*str < 0x80) ? 1 : 2; 681 {
682 int n = *str < 0x80 ? 1 : 2;
683 if (INT_ADD_OVERFLOW (bytes, n))
684 string_overflow ();
685 bytes += n;
686 }
682 return bytes; 687 return bytes;
683} 688}
684 689
diff --git a/src/character.h b/src/character.h
index 5877d145d9e..31e3b0a9416 100644
--- a/src/character.h
+++ b/src/character.h
@@ -602,7 +602,7 @@ extern int translate_char (Lisp_Object, int c);
602extern int char_printable_p (int c); 602extern int char_printable_p (int c);
603extern void parse_str_as_multibyte (const unsigned char *, 603extern void parse_str_as_multibyte (const unsigned char *,
604 EMACS_INT, EMACS_INT *, EMACS_INT *); 604 EMACS_INT, EMACS_INT *, EMACS_INT *);
605extern EMACS_INT parse_str_to_multibyte (const unsigned char *, EMACS_INT); 605extern EMACS_INT count_size_as_multibyte (const unsigned char *, EMACS_INT);
606extern EMACS_INT str_as_multibyte (unsigned char *, EMACS_INT, EMACS_INT, 606extern EMACS_INT str_as_multibyte (unsigned char *, EMACS_INT, EMACS_INT,
607 EMACS_INT *); 607 EMACS_INT *);
608extern EMACS_INT str_to_multibyte (unsigned char *, EMACS_INT, EMACS_INT); 608extern EMACS_INT str_to_multibyte (unsigned char *, EMACS_INT, EMACS_INT);
diff --git a/src/data.c b/src/data.c
index 577ae777d89..ce0e8e40f51 100644
--- a/src/data.c
+++ b/src/data.c
@@ -22,6 +22,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <signal.h> 22#include <signal.h>
23#include <stdio.h> 23#include <stdio.h>
24#include <setjmp.h> 24#include <setjmp.h>
25
26#include <intprops.h>
27
25#include "lisp.h" 28#include "lisp.h"
26#include "puresize.h" 29#include "puresize.h"
27#include "character.h" 30#include "character.h"
@@ -2431,6 +2434,10 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2431 register EMACS_INT accum = 0; 2434 register EMACS_INT accum = 0;
2432 register EMACS_INT next; 2435 register EMACS_INT next;
2433 2436
2437 int overflow = 0;
2438 size_t ok_args;
2439 EMACS_INT ok_accum;
2440
2434 switch (SWITCH_ENUM_CAST (code)) 2441 switch (SWITCH_ENUM_CAST (code))
2435 { 2442 {
2436 case Alogior: 2443 case Alogior:
@@ -2451,25 +2458,48 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2451 2458
2452 for (argnum = 0; argnum < nargs; argnum++) 2459 for (argnum = 0; argnum < nargs; argnum++)
2453 { 2460 {
2461 if (! overflow)
2462 {
2463 ok_args = argnum;
2464 ok_accum = accum;
2465 }
2466
2454 /* Using args[argnum] as argument to CHECK_NUMBER_... */ 2467 /* Using args[argnum] as argument to CHECK_NUMBER_... */
2455 val = args[argnum]; 2468 val = args[argnum];
2456 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); 2469 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val);
2457 2470
2458 if (FLOATP (val)) 2471 if (FLOATP (val))
2459 return float_arith_driver ((double) accum, argnum, code, 2472 return float_arith_driver (ok_accum, ok_args, code,
2460 nargs, args); 2473 nargs, args);
2461 args[argnum] = val; 2474 args[argnum] = val;
2462 next = XINT (args[argnum]); 2475 next = XINT (args[argnum]);
2463 switch (SWITCH_ENUM_CAST (code)) 2476 switch (SWITCH_ENUM_CAST (code))
2464 { 2477 {
2465 case Aadd: 2478 case Aadd:
2479 if (INT_ADD_OVERFLOW (accum, next))
2480 {
2481 overflow = 1;
2482 accum &= INTMASK;
2483 }
2466 accum += next; 2484 accum += next;
2467 break; 2485 break;
2468 case Asub: 2486 case Asub:
2487 if (INT_SUBTRACT_OVERFLOW (accum, next))
2488 {
2489 overflow = 1;
2490 accum &= INTMASK;
2491 }
2469 accum = argnum ? accum - next : nargs == 1 ? - next : next; 2492 accum = argnum ? accum - next : nargs == 1 ? - next : next;
2470 break; 2493 break;
2471 case Amult: 2494 case Amult:
2472 accum *= next; 2495 if (INT_MULTIPLY_OVERFLOW (accum, next))
2496 {
2497 EMACS_UINT a = accum, b = next, ab = a * b;
2498 overflow = 1;
2499 accum = ab & INTMASK;
2500 }
2501 else
2502 accum *= next;
2473 break; 2503 break;
2474 case Adiv: 2504 case Adiv:
2475 if (!argnum) 2505 if (!argnum)
@@ -2501,6 +2531,9 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2501 } 2531 }
2502 } 2532 }
2503 2533
2534 accum &= INTMASK;
2535 if (MOST_POSITIVE_FIXNUM < accum)
2536 accum += MOST_NEGATIVE_FIXNUM - (MOST_POSITIVE_FIXNUM + 1);
2504 XSETINT (val, accum); 2537 XSETINT (val, accum);
2505 return val; 2538 return val;
2506} 2539}
@@ -2760,11 +2793,11 @@ In this case, zeros are shifted in on the left. */)
2760 if (XINT (count) >= BITS_PER_EMACS_INT) 2793 if (XINT (count) >= BITS_PER_EMACS_INT)
2761 XSETINT (val, 0); 2794 XSETINT (val, 0);
2762 else if (XINT (count) > 0) 2795 else if (XINT (count) > 0)
2763 XSETINT (val, (EMACS_UINT) XUINT (value) << XFASTINT (count)); 2796 XSETINT (val, XUINT (value) << XFASTINT (count));
2764 else if (XINT (count) <= -BITS_PER_EMACS_INT) 2797 else if (XINT (count) <= -BITS_PER_EMACS_INT)
2765 XSETINT (val, 0); 2798 XSETINT (val, 0);
2766 else 2799 else
2767 XSETINT (val, (EMACS_UINT) XUINT (value) >> -XINT (count)); 2800 XSETINT (val, XUINT (value) >> -XINT (count));
2768 return val; 2801 return val;
2769} 2802}
2770 2803
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 80c52dc3bd0..d8d0c7c2ef0 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -242,6 +242,24 @@ xd_symbol_to_dbus_type (Lisp_Object object)
242#define XD_NEXT_VALUE(object) \ 242#define XD_NEXT_VALUE(object) \
243 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object) 243 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
244 244
245/* Check whether X is a valid dbus serial number. If valid, set
246 SERIAL to its value. Otherwise, signal an error. */
247#define CHECK_DBUS_SERIAL_GET_SERIAL(x, serial) \
248 do \
249 { \
250 dbus_uint32_t DBUS_SERIAL_MAX = -1; \
251 if (NATNUMP (x) && XINT (x) <= DBUS_SERIAL_MAX) \
252 serial = XINT (x); \
253 else if (MOST_POSITIVE_FIXNUM < DBUS_SERIAL_MAX \
254 && FLOATP (x) \
255 && 0 <= XFLOAT_DATA (x) \
256 && XFLOAT_DATA (x) <= DBUS_SERIAL_MAX) \
257 serial = XFLOAT_DATA (x); \
258 else \
259 XD_SIGNAL2 (build_string ("Invalid dbus serial"), x); \
260 } \
261 while (0)
262
245/* Compute SIGNATURE of OBJECT. It must have a form that it can be 263/* Compute SIGNATURE of OBJECT. It must have a form that it can be
246 used in dbus_message_iter_open_container. DTYPE is the DBusType 264 used in dbus_message_iter_open_container. DTYPE is the DBusType
247 the object is related to. It is passed as argument, because it 265 the object is related to. It is passed as argument, because it
@@ -431,9 +449,9 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter)
431 switch (dtype) 449 switch (dtype)
432 { 450 {
433 case DBUS_TYPE_BYTE: 451 case DBUS_TYPE_BYTE:
434 CHECK_NUMBER (object); 452 CHECK_NATNUM (object);
435 { 453 {
436 unsigned char val = XUINT (object) & 0xFF; 454 unsigned char val = XFASTINT (object) & 0xFF;
437 XD_DEBUG_MESSAGE ("%c %d", dtype, val); 455 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
438 if (!dbus_message_iter_append_basic (iter, dtype, &val)) 456 if (!dbus_message_iter_append_basic (iter, dtype, &val))
439 XD_SIGNAL2 (build_string ("Unable to append argument"), object); 457 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
@@ -460,9 +478,9 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter)
460 } 478 }
461 479
462 case DBUS_TYPE_UINT16: 480 case DBUS_TYPE_UINT16:
463 CHECK_NUMBER (object); 481 CHECK_NATNUM (object);
464 { 482 {
465 dbus_uint16_t val = XUINT (object); 483 dbus_uint16_t val = XFASTINT (object);
466 XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val); 484 XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
467 if (!dbus_message_iter_append_basic (iter, dtype, &val)) 485 if (!dbus_message_iter_append_basic (iter, dtype, &val))
468 XD_SIGNAL2 (build_string ("Unable to append argument"), object); 486 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
@@ -483,9 +501,9 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter)
483#ifdef DBUS_TYPE_UNIX_FD 501#ifdef DBUS_TYPE_UNIX_FD
484 case DBUS_TYPE_UNIX_FD: 502 case DBUS_TYPE_UNIX_FD:
485#endif 503#endif
486 CHECK_NUMBER (object); 504 CHECK_NATNUM (object);
487 { 505 {
488 dbus_uint32_t val = XUINT (object); 506 dbus_uint32_t val = XFASTINT (object);
489 XD_DEBUG_MESSAGE ("%c %u", dtype, val); 507 XD_DEBUG_MESSAGE ("%c %u", dtype, val);
490 if (!dbus_message_iter_append_basic (iter, dtype, &val)) 508 if (!dbus_message_iter_append_basic (iter, dtype, &val))
491 XD_SIGNAL2 (build_string ("Unable to append argument"), object); 509 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
@@ -503,10 +521,10 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter)
503 } 521 }
504 522
505 case DBUS_TYPE_UINT64: 523 case DBUS_TYPE_UINT64:
506 CHECK_NUMBER (object); 524 CHECK_NATNUM (object);
507 { 525 {
508 dbus_uint64_t val = XUINT (object); 526 dbus_uint64_t val = XFASTINT (object);
509 XD_DEBUG_MESSAGE ("%c %"pI"u", dtype, XUINT (object)); 527 XD_DEBUG_MESSAGE ("%c %"pI"d", dtype, XFASTINT (object));
510 if (!dbus_message_iter_append_basic (iter, dtype, &val)) 528 if (!dbus_message_iter_append_basic (iter, dtype, &val))
511 XD_SIGNAL2 (build_string ("Unable to append argument"), object); 529 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
512 return; 530 return;
@@ -1110,7 +1128,7 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &optional :timeout TI
1110 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout))) 1128 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
1111 { 1129 {
1112 CHECK_NATNUM (args[i+1]); 1130 CHECK_NATNUM (args[i+1]);
1113 timeout = XUINT (args[i+1]); 1131 timeout = XFASTINT (args[i+1]);
1114 i = i+2; 1132 i = i+2;
1115 } 1133 }
1116 1134
@@ -1186,7 +1204,7 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &optional :timeout TI
1186 1204
1187 /* Return the result. If there is only one single Lisp object, 1205 /* Return the result. If there is only one single Lisp object,
1188 return it as-it-is, otherwise return the reversed list. */ 1206 return it as-it-is, otherwise return the reversed list. */
1189 if (XUINT (Flength (result)) == 1) 1207 if (XFASTINT (Flength (result)) == 1)
1190 RETURN_UNGCPRO (CAR_SAFE (result)); 1208 RETURN_UNGCPRO (CAR_SAFE (result));
1191 else 1209 else
1192 RETURN_UNGCPRO (Fnreverse (result)); 1210 RETURN_UNGCPRO (Fnreverse (result));
@@ -1251,6 +1269,7 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE
1251 DBusMessage *dmessage; 1269 DBusMessage *dmessage;
1252 DBusMessageIter iter; 1270 DBusMessageIter iter;
1253 unsigned int dtype; 1271 unsigned int dtype;
1272 dbus_uint32_t serial;
1254 int timeout = -1; 1273 int timeout = -1;
1255 size_t i = 6; 1274 size_t i = 6;
1256 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; 1275 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
@@ -1292,7 +1311,7 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE
1292 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout))) 1311 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
1293 { 1312 {
1294 CHECK_NATNUM (args[i+1]); 1313 CHECK_NATNUM (args[i+1]);
1295 timeout = XUINT (args[i+1]); 1314 timeout = XFASTINT (args[i+1]);
1296 i = i+2; 1315 i = i+2;
1297 } 1316 }
1298 1317
@@ -1335,7 +1354,8 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE
1335 XD_SIGNAL1 (build_string ("Cannot send message")); 1354 XD_SIGNAL1 (build_string ("Cannot send message"));
1336 1355
1337 /* The result is the key in Vdbus_registered_objects_table. */ 1356 /* The result is the key in Vdbus_registered_objects_table. */
1338 result = (list2 (bus, make_number (dbus_message_get_serial (dmessage)))); 1357 serial = dbus_message_get_serial (dmessage);
1358 result = list2 (bus, make_fixnum_or_float (serial));
1339 1359
1340 /* Create a hash table entry. */ 1360 /* Create a hash table entry. */
1341 Fputhash (result, handler, Vdbus_registered_objects_table); 1361 Fputhash (result, handler, Vdbus_registered_objects_table);
@@ -1368,25 +1388,26 @@ This is an internal function, it shall not be used outside dbus.el.
1368usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */) 1388usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */)
1369 (size_t nargs, register Lisp_Object *args) 1389 (size_t nargs, register Lisp_Object *args)
1370{ 1390{
1371 Lisp_Object bus, serial, service; 1391 Lisp_Object bus, service;
1372 struct gcpro gcpro1, gcpro2, gcpro3; 1392 struct gcpro gcpro1, gcpro2;
1373 DBusConnection *connection; 1393 DBusConnection *connection;
1374 DBusMessage *dmessage; 1394 DBusMessage *dmessage;
1375 DBusMessageIter iter; 1395 DBusMessageIter iter;
1376 unsigned int dtype; 1396 dbus_uint32_t serial;
1397 unsigned int ui_serial, dtype;
1377 size_t i; 1398 size_t i;
1378 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; 1399 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1379 1400
1380 /* Check parameters. */ 1401 /* Check parameters. */
1381 bus = args[0]; 1402 bus = args[0];
1382 serial = args[1];
1383 service = args[2]; 1403 service = args[2];
1384 1404
1385 CHECK_NUMBER (serial); 1405 CHECK_DBUS_SERIAL_GET_SERIAL (args[1], serial);
1386 CHECK_STRING (service); 1406 CHECK_STRING (service);
1387 GCPRO3 (bus, serial, service); 1407 GCPRO2 (bus, service);
1388 1408
1389 XD_DEBUG_MESSAGE ("%"pI"u %s ", XUINT (serial), SDATA (service)); 1409 ui_serial = serial;
1410 XD_DEBUG_MESSAGE ("%u %s ", ui_serial, SSDATA (service));
1390 1411
1391 /* Open a connection to the bus. */ 1412 /* Open a connection to the bus. */
1392 connection = xd_initialize (bus, TRUE); 1413 connection = xd_initialize (bus, TRUE);
@@ -1394,7 +1415,7 @@ usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */)
1394 /* Create the message. */ 1415 /* Create the message. */
1395 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN); 1416 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
1396 if ((dmessage == NULL) 1417 if ((dmessage == NULL)
1397 || (!dbus_message_set_reply_serial (dmessage, XUINT (serial))) 1418 || (!dbus_message_set_reply_serial (dmessage, serial))
1398 || (!dbus_message_set_destination (dmessage, SSDATA (service)))) 1419 || (!dbus_message_set_destination (dmessage, SSDATA (service))))
1399 { 1420 {
1400 UNGCPRO; 1421 UNGCPRO;
@@ -1456,25 +1477,26 @@ This is an internal function, it shall not be used outside dbus.el.
1456usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */) 1477usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */)
1457 (size_t nargs, register Lisp_Object *args) 1478 (size_t nargs, register Lisp_Object *args)
1458{ 1479{
1459 Lisp_Object bus, serial, service; 1480 Lisp_Object bus, service;
1460 struct gcpro gcpro1, gcpro2, gcpro3; 1481 struct gcpro gcpro1, gcpro2;
1461 DBusConnection *connection; 1482 DBusConnection *connection;
1462 DBusMessage *dmessage; 1483 DBusMessage *dmessage;
1463 DBusMessageIter iter; 1484 DBusMessageIter iter;
1464 unsigned int dtype; 1485 dbus_uint32_t serial;
1486 unsigned int ui_serial, dtype;
1465 size_t i; 1487 size_t i;
1466 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; 1488 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1467 1489
1468 /* Check parameters. */ 1490 /* Check parameters. */
1469 bus = args[0]; 1491 bus = args[0];
1470 serial = args[1];
1471 service = args[2]; 1492 service = args[2];
1472 1493
1473 CHECK_NUMBER (serial); 1494 CHECK_DBUS_SERIAL_GET_SERIAL (args[1], serial);
1474 CHECK_STRING (service); 1495 CHECK_STRING (service);
1475 GCPRO3 (bus, serial, service); 1496 GCPRO2 (bus, service);
1476 1497
1477 XD_DEBUG_MESSAGE ("%"pI"u %s ", XUINT (serial), SDATA (service)); 1498 ui_serial = serial;
1499 XD_DEBUG_MESSAGE ("%u %s ", ui_serial, SSDATA (service));
1478 1500
1479 /* Open a connection to the bus. */ 1501 /* Open a connection to the bus. */
1480 connection = xd_initialize (bus, TRUE); 1502 connection = xd_initialize (bus, TRUE);
@@ -1483,7 +1505,7 @@ usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */)
1483 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR); 1505 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
1484 if ((dmessage == NULL) 1506 if ((dmessage == NULL)
1485 || (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED)) 1507 || (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED))
1486 || (!dbus_message_set_reply_serial (dmessage, XUINT (serial))) 1508 || (!dbus_message_set_reply_serial (dmessage, serial))
1487 || (!dbus_message_set_destination (dmessage, SSDATA (service)))) 1509 || (!dbus_message_set_destination (dmessage, SSDATA (service))))
1488 { 1510 {
1489 UNGCPRO; 1511 UNGCPRO;
@@ -1663,7 +1685,9 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1663 DBusMessage *dmessage; 1685 DBusMessage *dmessage;
1664 DBusMessageIter iter; 1686 DBusMessageIter iter;
1665 unsigned int dtype; 1687 unsigned int dtype;
1666 int mtype, serial; 1688 int mtype;
1689 dbus_uint32_t serial;
1690 unsigned int ui_serial;
1667 const char *uname, *path, *interface, *member; 1691 const char *uname, *path, *interface, *member;
1668 1692
1669 dmessage = dbus_connection_pop_message (connection); 1693 dmessage = dbus_connection_pop_message (connection);
@@ -1692,7 +1716,7 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1692 /* Read message type, message serial, unique name, object path, 1716 /* Read message type, message serial, unique name, object path,
1693 interface and member from the message. */ 1717 interface and member from the message. */
1694 mtype = dbus_message_get_type (dmessage); 1718 mtype = dbus_message_get_type (dmessage);
1695 serial = 1719 ui_serial = serial =
1696 ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) 1720 ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1697 || (mtype == DBUS_MESSAGE_TYPE_ERROR)) 1721 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1698 ? dbus_message_get_reply_serial (dmessage) 1722 ? dbus_message_get_reply_serial (dmessage)
@@ -1702,7 +1726,7 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1702 interface = dbus_message_get_interface (dmessage); 1726 interface = dbus_message_get_interface (dmessage);
1703 member = dbus_message_get_member (dmessage); 1727 member = dbus_message_get_member (dmessage);
1704 1728
1705 XD_DEBUG_MESSAGE ("Event received: %s %d %s %s %s %s %s", 1729 XD_DEBUG_MESSAGE ("Event received: %s %u %s %s %s %s %s",
1706 (mtype == DBUS_MESSAGE_TYPE_INVALID) 1730 (mtype == DBUS_MESSAGE_TYPE_INVALID)
1707 ? "DBUS_MESSAGE_TYPE_INVALID" 1731 ? "DBUS_MESSAGE_TYPE_INVALID"
1708 : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) 1732 : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
@@ -1712,14 +1736,14 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1712 : (mtype == DBUS_MESSAGE_TYPE_ERROR) 1736 : (mtype == DBUS_MESSAGE_TYPE_ERROR)
1713 ? "DBUS_MESSAGE_TYPE_ERROR" 1737 ? "DBUS_MESSAGE_TYPE_ERROR"
1714 : "DBUS_MESSAGE_TYPE_SIGNAL", 1738 : "DBUS_MESSAGE_TYPE_SIGNAL",
1715 serial, uname, path, interface, member, 1739 ui_serial, uname, path, interface, member,
1716 SDATA (format2 ("%s", args, Qnil))); 1740 SDATA (format2 ("%s", args, Qnil)));
1717 1741
1718 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) 1742 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1719 || (mtype == DBUS_MESSAGE_TYPE_ERROR)) 1743 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1720 { 1744 {
1721 /* Search for a registered function of the message. */ 1745 /* Search for a registered function of the message. */
1722 key = list2 (bus, make_number (serial)); 1746 key = list2 (bus, make_fixnum_or_float (serial));
1723 value = Fgethash (key, Vdbus_registered_objects_table, Qnil); 1747 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1724 1748
1725 /* There shall be exactly one entry. Construct an event. */ 1749 /* There shall be exactly one entry. Construct an event. */
@@ -1785,7 +1809,7 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1785 event.arg); 1809 event.arg);
1786 event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)), 1810 event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
1787 event.arg); 1811 event.arg);
1788 event.arg = Fcons (make_number (serial), event.arg); 1812 event.arg = Fcons (make_fixnum_or_float (serial), event.arg);
1789 event.arg = Fcons (make_number (mtype), event.arg); 1813 event.arg = Fcons (make_number (mtype), event.arg);
1790 1814
1791 /* Add the bus symbol to the event. */ 1815 /* Add the bus symbol to the event. */
diff --git a/src/editfns.c b/src/editfns.c
index 881e0c7f3e2..8b48355fbfa 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -45,9 +45,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
45#endif 45#endif
46 46
47#include <ctype.h> 47#include <ctype.h>
48#include <float.h>
48#include <limits.h> 49#include <limits.h>
49#include <intprops.h> 50#include <intprops.h>
50#include <strftime.h> 51#include <strftime.h>
52#include <verify.h>
51 53
52#include "intervals.h" 54#include "intervals.h"
53#include "buffer.h" 55#include "buffer.h"
@@ -57,13 +59,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
57#include "window.h" 59#include "window.h"
58#include "blockinput.h" 60#include "blockinput.h"
59 61
60#ifdef STDC_HEADERS
61#include <float.h>
62#define MAX_10_EXP DBL_MAX_10_EXP
63#else
64#define MAX_10_EXP 310
65#endif
66
67#ifndef NULL 62#ifndef NULL
68#define NULL 0 63#define NULL 0
69#endif 64#endif
@@ -3525,14 +3520,21 @@ usage: (propertize STRING &rest PROPERTIES) */)
3525 RETURN_UNGCPRO (string); 3520 RETURN_UNGCPRO (string);
3526} 3521}
3527 3522
3528 3523/* pWIDE is a conversion for printing large decimal integers (possibly with a
3529/* Number of bytes that STRING will occupy when put into the result. 3524 trailing "d" that is ignored). pWIDElen is its length. signed_wide and
3530 MULTIBYTE is nonzero if the result should be multibyte. */ 3525 unsigned_wide are signed and unsigned types for printing them. Use widest
3531 3526 integers if available so that more floating point values can be converted. */
3532#define CONVERTED_BYTE_SIZE(MULTIBYTE, STRING) \ 3527#ifdef PRIdMAX
3533 (((MULTIBYTE) && ! STRING_MULTIBYTE (STRING)) \ 3528# define pWIDE PRIdMAX
3534 ? count_size_as_multibyte (SDATA (STRING), SBYTES (STRING)) \ 3529enum { pWIDElen = sizeof PRIdMAX - 2 }; /* Don't count trailing "d". */
3535 : SBYTES (STRING)) 3530typedef intmax_t signed_wide;
3531typedef uintmax_t unsigned_wide;
3532#else
3533# define pWIDE pI
3534enum { pWIDElen = sizeof pI - 1 };
3535typedef EMACS_INT signed_wide;
3536typedef EMACS_UINT unsigned_wide;
3537#endif
3536 3538
3537DEFUN ("format", Fformat, Sformat, 1, MANY, 0, 3539DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
3538 doc: /* Format a string out of a format-string and arguments. 3540 doc: /* Format a string out of a format-string and arguments.
@@ -3583,11 +3585,17 @@ specifier truncates the string to the given width.
3583usage: (format STRING &rest OBJECTS) */) 3585usage: (format STRING &rest OBJECTS) */)
3584 (size_t nargs, register Lisp_Object *args) 3586 (size_t nargs, register Lisp_Object *args)
3585{ 3587{
3586 register size_t n; /* The number of the next arg to substitute */ 3588 EMACS_INT n; /* The number of the next arg to substitute */
3587 register size_t total; /* An estimate of the final length */ 3589 char initial_buffer[4000];
3588 char *buf, *p; 3590 char *buf = initial_buffer;
3591 EMACS_INT bufsize = sizeof initial_buffer;
3592 EMACS_INT max_bufsize = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX);
3593 char *p;
3594 Lisp_Object buf_save_value IF_LINT (= {0});
3589 register char *format, *end, *format_start; 3595 register char *format, *end, *format_start;
3590 int nchars; 3596 EMACS_INT formatlen, nchars;
3597 /* Nonzero if the format is multibyte. */
3598 int multibyte_format = 0;
3591 /* Nonzero if the output should be a multibyte string, 3599 /* Nonzero if the output should be a multibyte string,
3592 which is true if any of the inputs is one. */ 3600 which is true if any of the inputs is one. */
3593 int multibyte = 0; 3601 int multibyte = 0;
@@ -3596,14 +3604,6 @@ usage: (format STRING &rest OBJECTS) */)
3596 multibyte character of the previous string. This flag tells if we 3604 multibyte character of the previous string. This flag tells if we
3597 must consider such a situation or not. */ 3605 must consider such a situation or not. */
3598 int maybe_combine_byte; 3606 int maybe_combine_byte;
3599 char *this_format;
3600 /* Precision for each spec, or -1, a flag value meaning no precision
3601 was given in that spec. Element 0, corresponding to the format
3602 string itself, will not be used. Element NARGS, corresponding to
3603 no argument, *will* be assigned to in the case that a `%' and `.'
3604 occur after the final format specifier. */
3605 int *precision = (int *) (alloca ((nargs + 1) * sizeof (int)));
3606 int longest_format;
3607 Lisp_Object val; 3607 Lisp_Object val;
3608 int arg_intervals = 0; 3608 int arg_intervals = 0;
3609 USE_SAFE_ALLOCA; 3609 USE_SAFE_ALLOCA;
@@ -3611,458 +3611,603 @@ usage: (format STRING &rest OBJECTS) */)
3611 /* discarded[I] is 1 if byte I of the format 3611 /* discarded[I] is 1 if byte I of the format
3612 string was not copied into the output. 3612 string was not copied into the output.
3613 It is 2 if byte I was not the first byte of its character. */ 3613 It is 2 if byte I was not the first byte of its character. */
3614 char *discarded = 0; 3614 char *discarded;
3615 3615
3616 /* Each element records, for one argument, 3616 /* Each element records, for one argument,
3617 the start and end bytepos in the output string, 3617 the start and end bytepos in the output string,
3618 whether the argument has been converted to string (e.g., due to "%S"),
3618 and whether the argument is a string with intervals. 3619 and whether the argument is a string with intervals.
3619 info[0] is unused. Unused elements have -1 for start. */ 3620 info[0] is unused. Unused elements have -1 for start. */
3620 struct info 3621 struct info
3621 { 3622 {
3622 int start, end, intervals; 3623 EMACS_INT start, end;
3624 int converted_to_string;
3625 int intervals;
3623 } *info = 0; 3626 } *info = 0;
3624 3627
3625 /* It should not be necessary to GCPRO ARGS, because 3628 /* It should not be necessary to GCPRO ARGS, because
3626 the caller in the interpreter should take care of that. */ 3629 the caller in the interpreter should take care of that. */
3627 3630
3631 CHECK_STRING (args[0]);
3632 format_start = SSDATA (args[0]);
3633 formatlen = SBYTES (args[0]);
3634
3635 /* Allocate the info and discarded tables. */
3636 {
3637 EMACS_INT i;
3638 if ((SIZE_MAX - formatlen) / sizeof (struct info) <= nargs)
3639 memory_full ();
3640 SAFE_ALLOCA (info, struct info *, (nargs + 1) * sizeof *info + formatlen);
3641 discarded = (char *) &info[nargs + 1];
3642 for (i = 0; i < nargs + 1; i++)
3643 {
3644 info[i].start = -1;
3645 info[i].intervals = info[i].converted_to_string = 0;
3646 }
3647 memset (discarded, 0, formatlen);
3648 }
3649
3628 /* Try to determine whether the result should be multibyte. 3650 /* Try to determine whether the result should be multibyte.
3629 This is not always right; sometimes the result needs to be multibyte 3651 This is not always right; sometimes the result needs to be multibyte
3630 because of an object that we will pass through prin1, 3652 because of an object that we will pass through prin1,
3631 and in that case, we won't know it here. */ 3653 and in that case, we won't know it here. */
3632 for (n = 0; n < nargs; n++) 3654 multibyte_format = STRING_MULTIBYTE (args[0]);
3633 { 3655 multibyte = multibyte_format;
3634 if (STRINGP (args[n]) && STRING_MULTIBYTE (args[n])) 3656 for (n = 1; !multibyte && n < nargs; n++)
3635 multibyte = 1; 3657 if (STRINGP (args[n]) && STRING_MULTIBYTE (args[n]))
3636 /* Piggyback on this loop to initialize precision[N]. */ 3658 multibyte = 1;
3637 precision[n] = -1;
3638 }
3639 precision[nargs] = -1;
3640
3641 CHECK_STRING (args[0]);
3642 /* We may have to change "%S" to "%s". */
3643 args[0] = Fcopy_sequence (args[0]);
3644
3645 /* GC should never happen here, so abort if it does. */
3646 abort_on_gc++;
3647 3659
3648 /* If we start out planning a unibyte result, 3660 /* If we start out planning a unibyte result,
3649 then discover it has to be multibyte, we jump back to retry. 3661 then discover it has to be multibyte, we jump back to retry. */
3650 That can only happen from the first large while loop below. */
3651 retry: 3662 retry:
3652 3663
3653 format = SSDATA (args[0]); 3664 p = buf;
3654 format_start = format; 3665 nchars = 0;
3655 end = format + SBYTES (args[0]); 3666 n = 0;
3656 longest_format = 0;
3657
3658 /* Make room in result for all the non-%-codes in the control string. */
3659 total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]) + 1;
3660
3661 /* Allocate the info and discarded tables. */
3662 {
3663 size_t nbytes = (nargs+1) * sizeof *info;
3664 size_t i;
3665 if (!info)
3666 info = (struct info *) alloca (nbytes);
3667 memset (info, 0, nbytes);
3668 for (i = 0; i < nargs + 1; i++)
3669 info[i].start = -1;
3670 if (!discarded)
3671 SAFE_ALLOCA (discarded, char *, SBYTES (args[0]));
3672 memset (discarded, 0, SBYTES (args[0]));
3673 }
3674 3667
3675 /* Add to TOTAL enough space to hold the converted arguments. */ 3668 /* Scan the format and store result in BUF. */
3669 format = format_start;
3670 end = format + formatlen;
3671 maybe_combine_byte = 0;
3676 3672
3677 n = 0;
3678 while (format != end) 3673 while (format != end)
3679 if (*format++ == '%') 3674 {
3680 { 3675 /* The values of N and FORMAT when the loop body is entered. */
3681 EMACS_INT thissize = 0; 3676 EMACS_INT n0 = n;
3682 EMACS_INT actual_width = 0; 3677 char *format0 = format;
3683 char *this_format_start = format - 1;
3684 int field_width = 0;
3685 3678
3686 /* General format specifications look like 3679 /* Bytes needed to represent the output of this conversion. */
3680 EMACS_INT convbytes;
3687 3681
3688 '%' [flags] [field-width] [precision] format 3682 if (*format == '%')
3683 {
3684 /* General format specifications look like
3689 3685
3690 where 3686 '%' [flags] [field-width] [precision] format
3691 3687
3692 flags ::= [-+ #0]+ 3688 where
3693 field-width ::= [0-9]+
3694 precision ::= '.' [0-9]*
3695 3689
3696 If a field-width is specified, it specifies to which width 3690 flags ::= [-+0# ]+
3697 the output should be padded with blanks, if the output 3691 field-width ::= [0-9]+
3698 string is shorter than field-width. 3692 precision ::= '.' [0-9]*
3699 3693
3700 If precision is specified, it specifies the number of 3694 If a field-width is specified, it specifies to which width
3701 digits to print after the '.' for floats, or the max. 3695 the output should be padded with blanks, if the output
3702 number of chars to print from a string. */ 3696 string is shorter than field-width.
3703 3697
3704 while (format != end 3698 If precision is specified, it specifies the number of
3705 && (*format == '-' || *format == '0' || *format == '#' 3699 digits to print after the '.' for floats, or the max.
3706 || * format == ' ' || *format == '+')) 3700 number of chars to print from a string. */
3707 ++format;
3708 3701
3709 if (*format >= '0' && *format <= '9') 3702 int minus_flag = 0;
3710 { 3703 int plus_flag = 0;
3711 for (field_width = 0; *format >= '0' && *format <= '9'; ++format) 3704 int space_flag = 0;
3712 field_width = 10 * field_width + *format - '0'; 3705 int sharp_flag = 0;
3713 } 3706 int zero_flag = 0;
3707 EMACS_INT field_width;
3708 int precision_given;
3709 uintmax_t precision = UINTMAX_MAX;
3710 char *num_end;
3711 char conversion;
3714 3712
3715 /* N is not incremented for another few lines below, so refer to 3713 while (1)
3716 element N+1 (which might be precision[NARGS]). */ 3714 {
3717 if (*format == '.') 3715 switch (*++format)
3718 { 3716 {
3719 ++format; 3717 case '-': minus_flag = 1; continue;
3720 for (precision[n+1] = 0; *format >= '0' && *format <= '9'; ++format) 3718 case '+': plus_flag = 1; continue;
3721 precision[n+1] = 10 * precision[n+1] + *format - '0'; 3719 case ' ': space_flag = 1; continue;
3722 } 3720 case '#': sharp_flag = 1; continue;
3721 case '0': zero_flag = 1; continue;
3722 }
3723 break;
3724 }
3723 3725
3724 /* Extra +1 for 'l' that we may need to insert into the 3726 /* Ignore flags when sprintf ignores them. */
3725 format. */ 3727 space_flag &= ~ plus_flag;
3726 if (format - this_format_start + 2 > longest_format) 3728 zero_flag &= ~ minus_flag;
3727 longest_format = format - this_format_start + 2;
3728 3729
3729 if (format == end)
3730 error ("Format string ends in middle of format specifier");
3731 if (*format == '%')
3732 format++;
3733 else if (++n >= nargs)
3734 error ("Not enough arguments for format string");
3735 else if (*format == 'S')
3736 { 3730 {
3737 /* For `S', prin1 the argument and then treat like a string. */ 3731 uintmax_t w = strtoumax (format, &num_end, 10);
3738 register Lisp_Object tem; 3732 if (max_bufsize <= w)
3739 tem = Fprin1_to_string (args[n], Qnil); 3733 string_overflow ();
3740 if (STRING_MULTIBYTE (tem) && ! multibyte) 3734 field_width = w;
3741 {
3742 multibyte = 1;
3743 goto retry;
3744 }
3745 args[n] = tem;
3746 /* If we restart the loop, we should not come here again
3747 because args[n] is now a string and calling
3748 Fprin1_to_string on it produces superflous double
3749 quotes. So, change "%S" to "%s" now. */
3750 *format = 's';
3751 goto string;
3752 } 3735 }
3753 else if (SYMBOLP (args[n])) 3736 precision_given = *num_end == '.';
3754 { 3737 if (precision_given)
3755 args[n] = SYMBOL_NAME (args[n]); 3738 precision = strtoumax (num_end + 1, &num_end, 10);
3756 if (STRING_MULTIBYTE (args[n]) && ! multibyte) 3739 format = num_end;
3757 { 3740
3758 multibyte = 1; 3741 if (format == end)
3759 goto retry; 3742 error ("Format string ends in middle of format specifier");
3760 } 3743
3761 goto string; 3744 memset (&discarded[format0 - format_start], 1, format - format0);
3762 } 3745 conversion = *format;
3763 else if (STRINGP (args[n])) 3746 if (conversion == '%')
3764 { 3747 goto copy_char;
3765 string:
3766 if (*format != 's' && *format != 'S')
3767 error ("Format specifier doesn't match argument type");
3768 /* In the case (PRECISION[N] > 0), THISSIZE may not need
3769 to be as large as is calculated here. Easy check for
3770 the case PRECISION = 0. */
3771 thissize = precision[n] ? CONVERTED_BYTE_SIZE (multibyte, args[n]) : 0;
3772 /* The precision also constrains how much of the argument
3773 string will finally appear (Bug#5710). */
3774 actual_width = lisp_string_width (args[n], -1, NULL, NULL);
3775 if (precision[n] != -1)
3776 actual_width = min (actual_width, precision[n]);
3777 }
3778 /* Would get MPV otherwise, since Lisp_Int's `point' to low memory. */
3779 else if (INTEGERP (args[n]) && *format != 's')
3780 {
3781 /* The following loop assumes the Lisp type indicates
3782 the proper way to pass the argument.
3783 So make sure we have a flonum if the argument should
3784 be a double. */
3785 if (*format == 'e' || *format == 'f' || *format == 'g')
3786 args[n] = Ffloat (args[n]);
3787 else
3788 if (*format != 'd' && *format != 'o' && *format != 'x'
3789 && *format != 'i' && *format != 'X' && *format != 'c')
3790 error ("Invalid format operation %%%c", *format);
3791
3792 thissize = 30 + (precision[n] > 0 ? precision[n] : 0);
3793 if (*format == 'c')
3794 {
3795 if (! ASCII_CHAR_P (XINT (args[n]))
3796 /* Note: No one can remember why we have to treat
3797 the character 0 as a multibyte character here.
3798 But, until it causes a real problem, let's
3799 don't change it. */
3800 || XINT (args[n]) == 0)
3801 {
3802 if (! multibyte)
3803 {
3804 multibyte = 1;
3805 goto retry;
3806 }
3807 args[n] = Fchar_to_string (args[n]);
3808 thissize = SBYTES (args[n]);
3809 }
3810 }
3811 }
3812 else if (FLOATP (args[n]) && *format != 's')
3813 {
3814 if (! (*format == 'e' || *format == 'f' || *format == 'g'))
3815 {
3816 if (*format != 'd' && *format != 'o' && *format != 'x'
3817 && *format != 'i' && *format != 'X' && *format != 'c')
3818 error ("Invalid format operation %%%c", *format);
3819 /* This fails unnecessarily if args[n] is bigger than
3820 most-positive-fixnum but smaller than MAXINT.
3821 These cases are important because we sometimes use floats
3822 to represent such integer values (typically such values
3823 come from UIDs or PIDs). */
3824 /* args[n] = Ftruncate (args[n], Qnil); */
3825 }
3826
3827 /* Note that we're using sprintf to print floats,
3828 so we have to take into account what that function
3829 prints. */
3830 /* Filter out flag value of -1. */
3831 thissize = (MAX_10_EXP + 100
3832 + (precision[n] > 0 ? precision[n] : 0));
3833 }
3834 else
3835 {
3836 /* Anything but a string, convert to a string using princ. */
3837 register Lisp_Object tem;
3838 tem = Fprin1_to_string (args[n], Qt);
3839 if (STRING_MULTIBYTE (tem) && ! multibyte)
3840 {
3841 multibyte = 1;
3842 goto retry;
3843 }
3844 args[n] = tem;
3845 goto string;
3846 }
3847
3848 thissize += max (0, field_width - actual_width);
3849 total += thissize + 4;
3850 }
3851
3852 abort_on_gc--;
3853
3854 /* Now we can no longer jump to retry.
3855 TOTAL and LONGEST_FORMAT are known for certain. */
3856
3857 this_format = (char *) alloca (longest_format + 1);
3858
3859 /* Allocate the space for the result.
3860 Note that TOTAL is an overestimate. */
3861 SAFE_ALLOCA (buf, char *, total);
3862
3863 p = buf;
3864 nchars = 0;
3865 n = 0;
3866
3867 /* Scan the format and store result in BUF. */
3868 format = SSDATA (args[0]);
3869 format_start = format;
3870 end = format + SBYTES (args[0]);
3871 maybe_combine_byte = 0;
3872 while (format != end)
3873 {
3874 if (*format == '%')
3875 {
3876 int minlen;
3877 int negative = 0;
3878 char *this_format_start = format;
3879
3880 discarded[format - format_start] = 1; 3748 discarded[format - format_start] = 1;
3881 format++; 3749 format++;
3882 3750
3883 while (strchr ("-+0# ", *format)) 3751 ++n;
3752 if (! (n < nargs))
3753 error ("Not enough arguments for format string");
3754
3755 /* For 'S', prin1 the argument, and then treat like 's'.
3756 For 's', princ any argument that is not a string or
3757 symbol. But don't do this conversion twice, which might
3758 happen after retrying. */
3759 if ((conversion == 'S'
3760 || (conversion == 's'
3761 && ! STRINGP (args[n]) && ! SYMBOLP (args[n]))))
3884 { 3762 {
3885 if (*format == '-') 3763 if (! info[n].converted_to_string)
3886 { 3764 {
3887 negative = 1; 3765 Lisp_Object noescape = conversion == 'S' ? Qnil : Qt;
3766 args[n] = Fprin1_to_string (args[n], noescape);
3767 info[n].converted_to_string = 1;
3768 if (STRING_MULTIBYTE (args[n]) && ! multibyte)
3769 {
3770 multibyte = 1;
3771 goto retry;
3772 }
3888 } 3773 }
3889 discarded[format - format_start] = 1; 3774 conversion = 's';
3890 ++format;
3891 } 3775 }
3776 else if (conversion == 'c')
3777 {
3778 if (FLOATP (args[n]))
3779 {
3780 double d = XFLOAT_DATA (args[n]);
3781 args[n] = make_number (FIXNUM_OVERFLOW_P (d) ? -1 : d);
3782 }
3892 3783
3893 minlen = atoi (format); 3784 if (INTEGERP (args[n]) && ! ASCII_CHAR_P (XINT (args[n])))
3785 {
3786 if (!multibyte)
3787 {
3788 multibyte = 1;
3789 goto retry;
3790 }
3791 args[n] = Fchar_to_string (args[n]);
3792 info[n].converted_to_string = 1;
3793 }
3894 3794
3895 while ((*format >= '0' && *format <= '9') || *format == '.') 3795 if (info[n].converted_to_string)
3896 { 3796 conversion = 's';
3897 discarded[format - format_start] = 1; 3797 zero_flag = 0;
3898 format++;
3899 } 3798 }
3900 3799
3901 if (*format++ == '%') 3800 if (SYMBOLP (args[n]))
3902 { 3801 {
3903 *p++ = '%'; 3802 args[n] = SYMBOL_NAME (args[n]);
3904 nchars++; 3803 if (STRING_MULTIBYTE (args[n]) && ! multibyte)
3905 continue; 3804 {
3805 multibyte = 1;
3806 goto retry;
3807 }
3906 } 3808 }
3907 3809
3908 ++n; 3810 if (conversion == 's')
3909
3910 discarded[format - format_start - 1] = 1;
3911 info[n].start = nchars;
3912
3913 if (STRINGP (args[n]))
3914 { 3811 {
3915 /* handle case (precision[n] >= 0) */ 3812 /* handle case (precision[n] >= 0) */
3916 3813
3917 int width, padding; 3814 EMACS_INT width, padding, nbytes;
3918 EMACS_INT nbytes, start;
3919 EMACS_INT nchars_string; 3815 EMACS_INT nchars_string;
3920 3816
3817 EMACS_INT prec = -1;
3818 if (precision_given && precision <= TYPE_MAXIMUM (EMACS_INT))
3819 prec = precision;
3820
3921 /* lisp_string_width ignores a precision of 0, but GNU 3821 /* lisp_string_width ignores a precision of 0, but GNU
3922 libc functions print 0 characters when the precision 3822 libc functions print 0 characters when the precision
3923 is 0. Imitate libc behavior here. Changing 3823 is 0. Imitate libc behavior here. Changing
3924 lisp_string_width is the right thing, and will be 3824 lisp_string_width is the right thing, and will be
3925 done, but meanwhile we work with it. */ 3825 done, but meanwhile we work with it. */
3926 3826
3927 if (precision[n] == 0) 3827 if (prec == 0)
3928 width = nchars_string = nbytes = 0; 3828 width = nchars_string = nbytes = 0;
3929 else if (precision[n] > 0)
3930 width = lisp_string_width (args[n], precision[n],
3931 &nchars_string, &nbytes);
3932 else 3829 else
3933 { /* no precision spec given for this argument */ 3830 {
3934 width = lisp_string_width (args[n], -1, NULL, NULL); 3831 EMACS_INT nch, nby;
3935 nbytes = SBYTES (args[n]); 3832 width = lisp_string_width (args[n], prec, &nch, &nby);
3936 nchars_string = SCHARS (args[n]); 3833 if (prec < 0)
3834 {
3835 nchars_string = SCHARS (args[n]);
3836 nbytes = SBYTES (args[n]);
3837 }
3838 else
3839 {
3840 nchars_string = nch;
3841 nbytes = nby;
3842 }
3937 } 3843 }
3938 3844
3939 /* If spec requires it, pad on right with spaces. */ 3845 convbytes = nbytes;
3940 padding = minlen - width; 3846 if (convbytes && multibyte && ! STRING_MULTIBYTE (args[n]))
3941 if (! negative) 3847 convbytes = count_size_as_multibyte (SDATA (args[n]), nbytes);
3942 while (padding-- > 0)
3943 {
3944 *p++ = ' ';
3945 ++nchars;
3946 }
3947 3848
3948 info[n].start = start = nchars; 3849 padding = width < field_width ? field_width - width : 0;
3949 nchars += nchars_string;
3950 3850
3951 if (p > buf 3851 if (max_bufsize - padding <= convbytes)
3952 && multibyte 3852 string_overflow ();
3953 && !ASCII_BYTE_P (*((unsigned char *) p - 1)) 3853 convbytes += padding;
3954 && STRING_MULTIBYTE (args[n]) 3854 if (convbytes <= buf + bufsize - p)
3955 && !CHAR_HEAD_P (SREF (args[n], 0))) 3855 {
3956 maybe_combine_byte = 1; 3856 if (! minus_flag)
3857 {
3858 memset (p, ' ', padding);
3859 p += padding;
3860 nchars += padding;
3861 }
3957 3862
3958 p += copy_text (SDATA (args[n]), (unsigned char *) p, 3863 if (p > buf
3959 nbytes, 3864 && multibyte
3960 STRING_MULTIBYTE (args[n]), multibyte); 3865 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
3866 && STRING_MULTIBYTE (args[n])
3867 && !CHAR_HEAD_P (SREF (args[n], 0)))
3868 maybe_combine_byte = 1;
3961 3869
3962 info[n].end = nchars; 3870 p += copy_text (SDATA (args[n]), (unsigned char *) p,
3871 nbytes,
3872 STRING_MULTIBYTE (args[n]), multibyte);
3963 3873
3964 if (negative) 3874 info[n].start = nchars;
3965 while (padding-- > 0) 3875 nchars += nchars_string;
3966 { 3876 info[n].end = nchars;
3967 *p++ = ' ';
3968 nchars++;
3969 }
3970 3877
3971 /* If this argument has text properties, record where 3878 if (minus_flag)
3972 in the result string it appears. */ 3879 {
3973 if (STRING_INTERVALS (args[n])) 3880 memset (p, ' ', padding);
3974 info[n].intervals = arg_intervals = 1; 3881 p += padding;
3882 nchars += padding;
3883 }
3884
3885 /* If this argument has text properties, record where
3886 in the result string it appears. */
3887 if (STRING_INTERVALS (args[n]))
3888 info[n].intervals = arg_intervals = 1;
3889
3890 continue;
3891 }
3975 } 3892 }
3976 else if (INTEGERP (args[n]) || FLOATP (args[n])) 3893 else if (! (conversion == 'c' || conversion == 'd'
3894 || conversion == 'e' || conversion == 'f'
3895 || conversion == 'g' || conversion == 'i'
3896 || conversion == 'o' || conversion == 'x'
3897 || conversion == 'X'))
3898 error ("Invalid format operation %%%c",
3899 STRING_CHAR ((unsigned char *) format - 1));
3900 else if (! (INTEGERP (args[n]) || FLOATP (args[n])))
3901 error ("Format specifier doesn't match argument type");
3902 else
3977 { 3903 {
3978 int this_nchars; 3904 enum
3979 3905 {
3980 memcpy (this_format, this_format_start, 3906 /* Maximum precision for a %f conversion such that the
3981 format - this_format_start); 3907 trailing output digit might be nonzero. Any precisions
3982 this_format[format - this_format_start] = 0; 3908 larger than this will not yield useful information. */
3909 USEFUL_PRECISION_MAX =
3910 ((1 - DBL_MIN_EXP)
3911 * (FLT_RADIX == 2 || FLT_RADIX == 10 ? 1
3912 : FLT_RADIX == 16 ? 4
3913 : -1)),
3914
3915 /* Maximum number of bytes generated by any format, if
3916 precision is no more than DBL_USEFUL_PRECISION_MAX.
3917 On all practical hosts, %f is the worst case. */
3918 SPRINTF_BUFSIZE =
3919 sizeof "-." + (DBL_MAX_10_EXP + 1) + USEFUL_PRECISION_MAX
3920 };
3921 verify (0 < USEFUL_PRECISION_MAX);
3922
3923 int prec;
3924 EMACS_INT padding, sprintf_bytes;
3925 uintmax_t excess_precision, numwidth;
3926 uintmax_t leading_zeros = 0, trailing_zeros = 0;
3927
3928 char sprintf_buf[SPRINTF_BUFSIZE];
3929
3930 /* Copy of conversion specification, modified somewhat.
3931 At most three flags F can be specified at once. */
3932 char convspec[sizeof "%FFF.*d" + pWIDElen];
3933
3934 /* Avoid undefined behavior in underlying sprintf. */
3935 if (conversion == 'd' || conversion == 'i')
3936 sharp_flag = 0;
3937
3938 /* Create the copy of the conversion specification, with
3939 any width and precision removed, with ".*" inserted,
3940 and with pWIDE inserted for integer formats. */
3941 {
3942 char *f = convspec;
3943 *f++ = '%';
3944 *f = '-'; f += minus_flag;
3945 *f = '+'; f += plus_flag;
3946 *f = ' '; f += space_flag;
3947 *f = '#'; f += sharp_flag;
3948 *f = '0'; f += zero_flag;
3949 *f++ = '.';
3950 *f++ = '*';
3951 if (conversion == 'd' || conversion == 'i'
3952 || conversion == 'o' || conversion == 'x'
3953 || conversion == 'X')
3954 {
3955 memcpy (f, pWIDE, pWIDElen);
3956 f += pWIDElen;
3957 zero_flag &= ~ precision_given;
3958 }
3959 *f++ = conversion;
3960 *f = '\0';
3961 }
3983 3962
3984 if (format[-1] == 'e' || format[-1] == 'f' || format[-1] == 'g') 3963 prec = -1;
3985 sprintf (p, this_format, XFLOAT_DATA (args[n])); 3964 if (precision_given)
3965 prec = min (precision, USEFUL_PRECISION_MAX);
3966
3967 /* Use sprintf to format this number into sprintf_buf. Omit
3968 padding and excess precision, though, because sprintf limits
3969 output length to INT_MAX.
3970
3971 There are four types of conversion: double, unsigned
3972 char (passed as int), wide signed int, and wide
3973 unsigned int. Treat them separately because the
3974 sprintf ABI is sensitive to which type is passed. Be
3975 careful about integer overflow, NaNs, infinities, and
3976 conversions; for example, the min and max macros are
3977 not suitable here. */
3978 if (conversion == 'e' || conversion == 'f' || conversion == 'g')
3979 {
3980 double x = (INTEGERP (args[n])
3981 ? XINT (args[n])
3982 : XFLOAT_DATA (args[n]));
3983 sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
3984 }
3985 else if (conversion == 'c')
3986 {
3987 /* Don't use sprintf here, as it might mishandle prec. */
3988 sprintf_buf[0] = XINT (args[n]);
3989 sprintf_bytes = prec != 0;
3990 }
3991 else if (conversion == 'd')
3992 {
3993 /* For float, maybe we should use "%1.0f"
3994 instead so it also works for values outside
3995 the integer range. */
3996 signed_wide x;
3997 if (INTEGERP (args[n]))
3998 x = XINT (args[n]);
3999 else
4000 {
4001 double d = XFLOAT_DATA (args[n]);
4002 if (d < 0)
4003 {
4004 x = TYPE_MINIMUM (signed_wide);
4005 if (x < d)
4006 x = d;
4007 }
4008 else
4009 {
4010 x = TYPE_MAXIMUM (signed_wide);
4011 if (d < x)
4012 x = d;
4013 }
4014 }
4015 sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
4016 }
3986 else 4017 else
3987 { 4018 {
3988 if (sizeof (EMACS_INT) > sizeof (int) 4019 /* Don't sign-extend for octal or hex printing. */
3989 && format[-1] != 'c') 4020 unsigned_wide x;
4021 if (INTEGERP (args[n]))
4022 x = XUINT (args[n]);
4023 else
3990 { 4024 {
3991 /* Insert 'l' before format spec. */ 4025 double d = XFLOAT_DATA (args[n]);
3992 this_format[format - this_format_start] 4026 if (d < 0)
3993 = this_format[format - this_format_start - 1]; 4027 x = 0;
3994 this_format[format - this_format_start - 1] = 'l'; 4028 else
3995 this_format[format - this_format_start + 1] = 0; 4029 {
4030 x = TYPE_MAXIMUM (unsigned_wide);
4031 if (d < x)
4032 x = d;
4033 }
3996 } 4034 }
4035 sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
4036 }
3997 4037
3998 if (INTEGERP (args[n])) 4038 /* Now the length of the formatted item is known, except it omits
4039 padding and excess precision. Deal with excess precision
4040 first. This happens only when the format specifies
4041 ridiculously large precision. */
4042 excess_precision = precision - prec;
4043 if (excess_precision)
4044 {
4045 if (conversion == 'e' || conversion == 'f'
4046 || conversion == 'g')
3999 { 4047 {
4000 if (format[-1] == 'c') 4048 if ((conversion == 'g' && ! sharp_flag)
4001 sprintf (p, this_format, (int) XINT (args[n])); 4049 || ! ('0' <= sprintf_buf[sprintf_bytes - 1]
4002 else if (format[-1] == 'd') 4050 && sprintf_buf[sprintf_bytes - 1] <= '9'))
4003 sprintf (p, this_format, XINT (args[n])); 4051 excess_precision = 0;
4004 /* Don't sign-extend for octal or hex printing. */
4005 else 4052 else
4006 sprintf (p, this_format, XUINT (args[n])); 4053 {
4054 if (conversion == 'g')
4055 {
4056 char *dot = strchr (sprintf_buf, '.');
4057 if (!dot)
4058 excess_precision = 0;
4059 }
4060 }
4061 trailing_zeros = excess_precision;
4007 } 4062 }
4008 else if (format[-1] == 'c')
4009 sprintf (p, this_format, (int) XFLOAT_DATA (args[n]));
4010 else if (format[-1] == 'd')
4011 /* Maybe we should use "%1.0f" instead so it also works
4012 for values larger than MAXINT. */
4013 sprintf (p, this_format, (EMACS_INT) XFLOAT_DATA (args[n]));
4014 else 4063 else
4015 /* Don't sign-extend for octal or hex printing. */ 4064 leading_zeros = excess_precision;
4016 sprintf (p, this_format, (EMACS_UINT) XFLOAT_DATA (args[n])); 4065 }
4066
4067 /* Compute the total bytes needed for this item, including
4068 excess precision and padding. */
4069 numwidth = sprintf_bytes + excess_precision;
4070 padding = numwidth < field_width ? field_width - numwidth : 0;
4071 if (max_bufsize - sprintf_bytes <= excess_precision
4072 || max_bufsize - padding <= numwidth)
4073 string_overflow ();
4074 convbytes = numwidth + padding;
4075
4076 if (convbytes <= buf + bufsize - p)
4077 {
4078 /* Copy the formatted item from sprintf_buf into buf,
4079 inserting padding and excess-precision zeros. */
4080
4081 char *src = sprintf_buf;
4082 char src0 = src[0];
4083 int exponent_bytes = 0;
4084 int signedp = src0 == '-' || src0 == '+' || src0 == ' ';
4085 int significand_bytes;
4086 if (zero_flag && '0' <= src[signedp] && src[signedp] <= '9')
4087 {
4088 leading_zeros += padding;
4089 padding = 0;
4090 }
4091
4092 if (excess_precision
4093 && (conversion == 'e' || conversion == 'g'))
4094 {
4095 char *e = strchr (src, 'e');
4096 if (e)
4097 exponent_bytes = src + sprintf_bytes - e;
4098 }
4099
4100 if (! minus_flag)
4101 {
4102 memset (p, ' ', padding);
4103 p += padding;
4104 nchars += padding;
4105 }
4106
4107 *p = src0;
4108 src += signedp;
4109 p += signedp;
4110 memset (p, '0', leading_zeros);
4111 p += leading_zeros;
4112 significand_bytes = sprintf_bytes - signedp - exponent_bytes;
4113 memcpy (p, src, significand_bytes);
4114 p += significand_bytes;
4115 src += significand_bytes;
4116 memset (p, '0', trailing_zeros);
4117 p += trailing_zeros;
4118 memcpy (p, src, exponent_bytes);
4119 p += exponent_bytes;
4120
4121 info[n].start = nchars;
4122 nchars += leading_zeros + sprintf_bytes + trailing_zeros;
4123 info[n].end = nchars;
4124
4125 if (minus_flag)
4126 {
4127 memset (p, ' ', padding);
4128 p += padding;
4129 nchars += padding;
4130 }
4131
4132 continue;
4017 } 4133 }
4134 }
4135 }
4136 else
4137 copy_char:
4138 {
4139 /* Copy a single character from format to buf. */
4140
4141 char *src = format;
4142 unsigned char str[MAX_MULTIBYTE_LENGTH];
4018 4143
4144 if (multibyte_format)
4145 {
4146 /* Copy a whole multibyte character. */
4019 if (p > buf 4147 if (p > buf
4020 && multibyte
4021 && !ASCII_BYTE_P (*((unsigned char *) p - 1)) 4148 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
4022 && !CHAR_HEAD_P (*((unsigned char *) p))) 4149 && !CHAR_HEAD_P (*format))
4023 maybe_combine_byte = 1; 4150 maybe_combine_byte = 1;
4024 this_nchars = strlen (p); 4151
4025 if (multibyte) 4152 do
4026 p += str_to_multibyte ((unsigned char *) p, 4153 format++;
4027 buf + total - 1 - p, this_nchars); 4154 while (! CHAR_HEAD_P (*format));
4155
4156 convbytes = format - format0;
4157 memset (&discarded[format0 + 1 - format_start], 2, convbytes - 1);
4158 }
4159 else
4160 {
4161 unsigned char uc = *format++;
4162 if (! multibyte || ASCII_BYTE_P (uc))
4163 convbytes = 1;
4028 else 4164 else
4029 p += this_nchars; 4165 {
4030 nchars += this_nchars; 4166 int c = BYTE8_TO_CHAR (uc);
4031 info[n].end = nchars; 4167 convbytes = CHAR_STRING (c, str);
4168 src = (char *) str;
4169 }
4032 } 4170 }
4033 4171
4034 } 4172 if (convbytes <= buf + bufsize - p)
4035 else if (STRING_MULTIBYTE (args[0]))
4036 {
4037 /* Copy a whole multibyte character. */
4038 if (p > buf
4039 && multibyte
4040 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
4041 && !CHAR_HEAD_P (*format))
4042 maybe_combine_byte = 1;
4043 *p++ = *format++;
4044 while (! CHAR_HEAD_P (*format))
4045 { 4173 {
4046 discarded[format - format_start] = 2; 4174 memcpy (p, src, convbytes);
4047 *p++ = *format++; 4175 p += convbytes;
4176 nchars++;
4177 continue;
4048 } 4178 }
4049 nchars++;
4050 } 4179 }
4051 else if (multibyte)
4052 {
4053 /* Convert a single-byte character to multibyte. */
4054 int len = copy_text ((unsigned char *) format, (unsigned char *) p,
4055 1, 0, 1);
4056 4180
4057 p += len; 4181 /* There wasn't enough room to store this conversion or single
4058 format++; 4182 character. CONVBYTES says how much room is needed. Allocate
4059 nchars++; 4183 enough room (and then some) and do it again. */
4060 } 4184 {
4061 else 4185 EMACS_INT used = p - buf;
4062 *p++ = *format++, nchars++; 4186
4187 if (max_bufsize - used < convbytes)
4188 string_overflow ();
4189 bufsize = used + convbytes;
4190 bufsize = bufsize < max_bufsize / 2 ? bufsize * 2 : max_bufsize;
4191
4192 if (buf == initial_buffer)
4193 {
4194 buf = xmalloc (bufsize);
4195 sa_must_free = 1;
4196 buf_save_value = make_save_value (buf, 0);
4197 record_unwind_protect (safe_alloca_unwind, buf_save_value);
4198 memcpy (buf, initial_buffer, used);
4199 }
4200 else
4201 XSAVE_VALUE (buf_save_value)->pointer = buf = xrealloc (buf, bufsize);
4202
4203 p = buf + used;
4204 }
4205
4206 format = format0;
4207 n = n0;
4063 } 4208 }
4064 4209
4065 if (p > buf + total) 4210 if (bufsize < p - buf)
4066 abort (); 4211 abort ();
4067 4212
4068 if (maybe_combine_byte) 4213 if (maybe_combine_byte)
@@ -4089,7 +4234,7 @@ usage: (format STRING &rest OBJECTS) */)
4089 if (CONSP (props)) 4234 if (CONSP (props))
4090 { 4235 {
4091 EMACS_INT bytepos = 0, position = 0, translated = 0; 4236 EMACS_INT bytepos = 0, position = 0, translated = 0;
4092 int argn = 1; 4237 EMACS_INT argn = 1;
4093 Lisp_Object list; 4238 Lisp_Object list;
4094 4239
4095 /* Adjust the bounds of each text property 4240 /* Adjust the bounds of each text property
diff --git a/src/fns.c b/src/fns.c
index aee7281cf00..3e772d59239 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -898,7 +898,7 @@ string_to_multibyte (Lisp_Object string)
898 if (STRING_MULTIBYTE (string)) 898 if (STRING_MULTIBYTE (string))
899 return string; 899 return string;
900 900
901 nbytes = parse_str_to_multibyte (SDATA (string), SBYTES (string)); 901 nbytes = count_size_as_multibyte (SDATA (string), SBYTES (string));
902 /* If all the chars are ASCII, they won't need any more bytes once 902 /* If all the chars are ASCII, they won't need any more bytes once
903 converted. */ 903 converted. */
904 if (nbytes == SBYTES (string)) 904 if (nbytes == SBYTES (string))
diff --git a/src/insdel.c b/src/insdel.c
index de9e8aa570a..c0cccc65d6a 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -570,37 +570,6 @@ copy_text (const unsigned char *from_addr, unsigned char *to_addr,
570 return to_addr - initial_to_addr; 570 return to_addr - initial_to_addr;
571 } 571 }
572} 572}
573
574/* Return the number of bytes it would take
575 to convert some single-byte text to multibyte.
576 The single-byte text consists of NBYTES bytes at PTR. */
577
578EMACS_INT
579count_size_as_multibyte (const unsigned char *ptr, EMACS_INT nbytes)
580{
581 EMACS_INT i;
582 EMACS_INT outgoing_nbytes = 0;
583
584 for (i = 0; i < nbytes; i++)
585 {
586 unsigned int c = *ptr++;
587 int n;
588
589 if (ASCII_CHAR_P (c))
590 n = 1;
591 else
592 {
593 c = BYTE8_TO_CHAR (c);
594 n = CHAR_BYTES (c);
595 }
596
597 if (INT_ADD_OVERFLOW (outgoing_nbytes, n))
598 string_overflow ();
599 outgoing_nbytes += n;
600 }
601
602 return outgoing_nbytes;
603}
604 573
605/* Insert a string of specified length before point. 574/* Insert a string of specified length before point.
606 This function judges multibyteness based on 575 This function judges multibyteness based on
diff --git a/src/lisp.h b/src/lisp.h
index b6bf2bdb502..6618a754145 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -544,11 +544,10 @@ extern Lisp_Object make_number (EMACS_INT);
544 544
545/* Value is non-zero if I doesn't fit into a Lisp fixnum. It is 545/* Value is non-zero if I doesn't fit into a Lisp fixnum. It is
546 written this way so that it also works if I is of unsigned 546 written this way so that it also works if I is of unsigned
547 type. */ 547 type or if I is a NaN. */
548 548
549#define FIXNUM_OVERFLOW_P(i) \ 549#define FIXNUM_OVERFLOW_P(i) \
550 ((i) > MOST_POSITIVE_FIXNUM \ 550 (! ((0 <= (i) || MOST_NEGATIVE_FIXNUM <= (i)) && (i) <= MOST_POSITIVE_FIXNUM))
551 || ((i) < 0 && (i) < MOST_NEGATIVE_FIXNUM))
552 551
553/* Extract a value or address from a Lisp_Object. */ 552/* Extract a value or address from a Lisp_Object. */
554 553
@@ -2574,7 +2573,6 @@ extern void move_gap_both (EMACS_INT, EMACS_INT);
2574extern void make_gap (EMACS_INT); 2573extern void make_gap (EMACS_INT);
2575extern EMACS_INT copy_text (const unsigned char *, unsigned char *, 2574extern EMACS_INT copy_text (const unsigned char *, unsigned char *,
2576 EMACS_INT, int, int); 2575 EMACS_INT, int, int);
2577extern EMACS_INT count_size_as_multibyte (const unsigned char *, EMACS_INT);
2578extern int count_combining_before (const unsigned char *, 2576extern int count_combining_before (const unsigned char *,
2579 EMACS_INT, EMACS_INT, EMACS_INT); 2577 EMACS_INT, EMACS_INT, EMACS_INT);
2580extern int count_combining_after (const unsigned char *, 2578extern int count_combining_after (const unsigned char *,
diff --git a/src/mem-limits.h b/src/mem-limits.h
index 09be61be52c..aa3a13c1c34 100644
--- a/src/mem-limits.h
+++ b/src/mem-limits.h
@@ -40,8 +40,7 @@ extern char *start_of_data (void);
40#define EXCEEDS_LISP_PTR(ptr) 0 40#define EXCEEDS_LISP_PTR(ptr) 0
41#elif defined DATA_SEG_BITS 41#elif defined DATA_SEG_BITS
42#define EXCEEDS_LISP_PTR(ptr) \ 42#define EXCEEDS_LISP_PTR(ptr) \
43 (((EMACS_UINT) (ptr) & ~DATA_SEG_BITS) >> VALBITS) 43 (((uintptr_t) (ptr) & ~DATA_SEG_BITS) >> VALBITS)
44#else 44#else
45#define EXCEEDS_LISP_PTR(ptr) ((EMACS_UINT) (ptr) >> VALBITS) 45#define EXCEEDS_LISP_PTR(ptr) ((uintptr_t) (ptr) >> VALBITS)
46#endif 46#endif
47
diff --git a/src/print.c b/src/print.c
index f0624d5d16e..20c3e8ae526 100644
--- a/src/print.c
+++ b/src/print.c
@@ -381,7 +381,7 @@ print_string (Lisp_Object string, Lisp_Object printcharfun)
381 EMACS_INT bytes; 381 EMACS_INT bytes;
382 382
383 chars = SBYTES (string); 383 chars = SBYTES (string);
384 bytes = parse_str_to_multibyte (SDATA (string), chars); 384 bytes = count_size_as_multibyte (SDATA (string), chars);
385 if (chars < bytes) 385 if (chars < bytes)
386 { 386 {
387 newstr = make_uninit_multibyte_string (chars, bytes); 387 newstr = make_uninit_multibyte_string (chars, bytes);