aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-06-27 12:31:27 -0700
committerPaul Eggert2019-06-27 12:35:08 -0700
commit4893a09c005cac81c05cd3db05c87225be6a7b42 (patch)
tree1e1e193f61c97067076a1b2f0940c79d5e92ed33 /src
parent3502d4c1b587057c2f5907997f74ae0a2e0d2a7d (diff)
downloademacs-4893a09c005cac81c05cd3db05c87225be6a7b42.tar.gz
emacs-4893a09c005cac81c05cd3db05c87225be6a7b42.zip
Clean up use of XFIXNUM etc.
A few bits of the code were relying on the fact that XFIXNUM, XFIXNAT, and XUFIXNUM do something even with arguments that are not fixnums/fixnats. Separate these rare uses out into XFIXNUM_RAW and XUFIXNUM_RAW. Problem and original patch reported by Pip Cet (Bug#36370). * src/ccl.c (Fccl_execute_on_string): * src/fileio.c (Finsert_file_contents, a_write) (Fdo_auto_save): * src/process.c (conv_lisp_to_sockaddr): * src/textprop.c (Fnext_single_char_property_change) (Fprevious_single_char_property_change) (Fnext_property_change, Fnext_single_property_change) (Fprevious_property_change) (Fprevious_single_property_change): Don’t assume fixnums are nonnegative. * src/ccl.c (Fccl_execute_on_string): Fix range-checking bug if AREF (status, i) is out of int range. * src/data.c (arith_driver): Use XFIXNUM_RAW as we want efficient garbage if the value is not a fixnum. * src/dosfns.c (Fint86, Fdos_memput): Check that args are nonnegative. * src/image.c (lookup_image): Check that args are in range. * src/lisp.h (lisp_h_XHASH): Use XUFIXNUM_RAW, since this is for hashing. (lisp_h_XFIXNAT, XFIXNAT) [USE_LSB_TAG]: Remove macros. (lisp_h_XFIXNUM_RAW, XFIXNUM_RAW) [USE_LSB_TAG]: New macros, with the semantics of the old macros without _RAW. (XFIXNUM_RAW, XUFIXNUM_RAW): New inline functions, with the semantics of the old functions without _RAW. (FIXNUMP): Move definition up to avoid forward use. (XFIXNUM, XFIXNAT, XUFIXNUM): Use eassume to add a runtime check (when debugging) that the argument has the proper form. (XFIXNUM, XFIXNAT): Now inline functions only, since they refer to their arguments more than once now that they use eassume. * src/textprop.c (Fprevious_single_char_property_change): Avoid fixnum overflow with invalid input. (set_text_properties): Fix unlikely failure to validate arguments, by using EQ instead of XFIXNAT. * src/w32term.c (w32_draw_glyph_string): * src/xterm.c (x_draw_glyph_string): Treat negative minimums as 0 rather than as garbage patterns.
Diffstat (limited to 'src')
-rw-r--r--src/ccl.c6
-rw-r--r--src/data.c2
-rw-r--r--src/dosfns.c4
-rw-r--r--src/fileio.c6
-rw-r--r--src/image.c4
-rw-r--r--src/lisp.h75
-rw-r--r--src/process.c2
-rw-r--r--src/textprop.c29
-rw-r--r--src/w32term.c2
-rw-r--r--src/xterm.c2
10 files changed, 67 insertions, 65 deletions
diff --git a/src/ccl.c b/src/ccl.c
index ec108e30d86..f1d4c28df1c 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -2064,9 +2064,9 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
2064 } 2064 }
2065 if (FIXNUMP (AREF (status, i))) 2065 if (FIXNUMP (AREF (status, i)))
2066 { 2066 {
2067 i = XFIXNAT (AREF (status, 8)); 2067 EMACS_INT ic = XFIXNUM (AREF (status, i));
2068 if (ccl.ic < i && i < ccl.size) 2068 if (ccl.ic < ic && ic < ccl.size)
2069 ccl.ic = i; 2069 ccl.ic = ic;
2070 } 2070 }
2071 2071
2072 buf_magnification = ccl.buf_magnification ? ccl.buf_magnification : 1; 2072 buf_magnification = ccl.buf_magnification ? ccl.buf_magnification : 1;
diff --git a/src/data.c b/src/data.c
index c1699aeae73..46bd7e0e253 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2928,7 +2928,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args,
2928 ptrdiff_t argnum = 0; 2928 ptrdiff_t argnum = 0;
2929 /* Set ACCUM to VAL's value if it is a fixnum, otherwise to some 2929 /* Set ACCUM to VAL's value if it is a fixnum, otherwise to some
2930 ignored value to avoid using an uninitialized variable later. */ 2930 ignored value to avoid using an uninitialized variable later. */
2931 intmax_t accum = XFIXNUM (val); 2931 intmax_t accum = XFIXNUM_RAW (val);
2932 2932
2933 if (FIXNUMP (val)) 2933 if (FIXNUMP (val))
2934 while (true) 2934 while (true)
diff --git a/src/dosfns.c b/src/dosfns.c
index 47c545007ad..fb5bcc9ad3f 100644
--- a/src/dosfns.c
+++ b/src/dosfns.c
@@ -72,7 +72,7 @@ REGISTERS should be a vector produced by `make-register' and
72 if (no < 0 || no > 0xff || ASIZE (registers) != 8) 72 if (no < 0 || no > 0xff || ASIZE (registers) != 8)
73 return Qnil; 73 return Qnil;
74 for (i = 0; i < 8; i++) 74 for (i = 0; i < 8; i++)
75 CHECK_FIXNUM (AREF (registers, i)); 75 CHECK_FIXNAT (AREF (registers, i));
76 76
77 inregs.x.ax = (unsigned long) XFIXNAT (AREF (registers, 0)); 77 inregs.x.ax = (unsigned long) XFIXNAT (AREF (registers, 0));
78 inregs.x.bx = (unsigned long) XFIXNAT (AREF (registers, 1)); 78 inregs.x.bx = (unsigned long) XFIXNAT (AREF (registers, 1));
@@ -139,7 +139,7 @@ DEFUN ("msdos-memput", Fdos_memput, Sdos_memput, 2, 2, 0,
139 139
140 for (i = 0; i < len; i++) 140 for (i = 0; i < len; i++)
141 { 141 {
142 CHECK_FIXNUM (AREF (vector, i)); 142 CHECK_FIXNAT (AREF (vector, i));
143 buf[i] = (unsigned char) XFIXNAT (AREF (vector, i)) & 0xFF; 143 buf[i] = (unsigned char) XFIXNAT (AREF (vector, i)) & 0xFF;
144 } 144 }
145 145
diff --git a/src/fileio.c b/src/fileio.c
index 0da9894a73a..61e10dac47f 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4720,7 +4720,7 @@ by calling `format-decode', which see. */)
4720 Lisp_Object tem = XCAR (old_undo); 4720 Lisp_Object tem = XCAR (old_undo);
4721 if (CONSP (tem) && FIXNUMP (XCAR (tem)) 4721 if (CONSP (tem) && FIXNUMP (XCAR (tem))
4722 && FIXNUMP (XCDR (tem)) 4722 && FIXNUMP (XCDR (tem))
4723 && XFIXNAT (XCDR (tem)) == PT + old_inserted) 4723 && XFIXNUM (XCDR (tem)) == PT + old_inserted)
4724 XSETCDR (tem, make_fixnum (PT + inserted)); 4724 XSETCDR (tem, make_fixnum (PT + inserted));
4725 } 4725 }
4726 } 4726 }
@@ -5392,7 +5392,7 @@ a_write (int desc, Lisp_Object string, ptrdiff_t pos,
5392 tem = Fcar_safe (Fcar (*annot)); 5392 tem = Fcar_safe (Fcar (*annot));
5393 nextpos = pos - 1; 5393 nextpos = pos - 1;
5394 if (FIXNUMP (tem)) 5394 if (FIXNUMP (tem))
5395 nextpos = XFIXNAT (tem); 5395 nextpos = XFIXNUM (tem);
5396 5396
5397 /* If there are no more annotations in this range, 5397 /* If there are no more annotations in this range,
5398 output the rest of the range all at once. */ 5398 output the rest of the range all at once. */
@@ -5850,7 +5850,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5850 && FIXNUMP (BVAR (b, save_length)) 5850 && FIXNUMP (BVAR (b, save_length))
5851 /* A short file is likely to change a large fraction; 5851 /* A short file is likely to change a large fraction;
5852 spare the user annoying messages. */ 5852 spare the user annoying messages. */
5853 && XFIXNAT (BVAR (b, save_length)) > 5000 5853 && XFIXNUM (BVAR (b, save_length)) > 5000
5854 && (growth_factor * (BUF_Z (b) - BUF_BEG (b)) 5854 && (growth_factor * (BUF_Z (b) - BUF_BEG (b))
5855 < (growth_factor - 1) * XFIXNAT (BVAR (b, save_length))) 5855 < (growth_factor - 1) * XFIXNAT (BVAR (b, save_length)))
5856 /* These messages are frequent and annoying for `*mail*'. */ 5856 /* These messages are frequent and annoying for `*mail*'. */
diff --git a/src/image.c b/src/image.c
index e684aedb99f..bbf25b4d58f 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2385,13 +2385,13 @@ lookup_image (struct frame *f, Lisp_Object spec)
2385#endif 2385#endif
2386 2386
2387 ascent = image_spec_value (spec, QCascent, NULL); 2387 ascent = image_spec_value (spec, QCascent, NULL);
2388 if (FIXNUMP (ascent)) 2388 if (RANGED_FIXNUMP (0, ascent, INT_MAX))
2389 img->ascent = XFIXNAT (ascent); 2389 img->ascent = XFIXNAT (ascent);
2390 else if (EQ (ascent, Qcenter)) 2390 else if (EQ (ascent, Qcenter))
2391 img->ascent = CENTERED_IMAGE_ASCENT; 2391 img->ascent = CENTERED_IMAGE_ASCENT;
2392 2392
2393 margin = image_spec_value (spec, QCmargin, NULL); 2393 margin = image_spec_value (spec, QCmargin, NULL);
2394 if (FIXNUMP (margin)) 2394 if (RANGED_FIXNUMP (0, margin, INT_MAX))
2395 img->vmargin = img->hmargin = XFIXNAT (margin); 2395 img->vmargin = img->hmargin = XFIXNAT (margin);
2396 else if (CONSP (margin)) 2396 else if (CONSP (margin))
2397 { 2397 {
diff --git a/src/lisp.h b/src/lisp.h
index 77fc22d1187..077d2360654 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -414,12 +414,11 @@ typedef EMACS_INT Lisp_Word;
414#define lisp_h_XCDR(c) XCONS (c)->u.s.u.cdr 414#define lisp_h_XCDR(c) XCONS (c)->u.s.u.cdr
415#define lisp_h_XCONS(a) \ 415#define lisp_h_XCONS(a) \
416 (eassert (CONSP (a)), XUNTAG (a, Lisp_Cons, struct Lisp_Cons)) 416 (eassert (CONSP (a)), XUNTAG (a, Lisp_Cons, struct Lisp_Cons))
417#define lisp_h_XHASH(a) XUFIXNUM (a) 417#define lisp_h_XHASH(a) XUFIXNUM_RAW (a)
418#if USE_LSB_TAG 418#if USE_LSB_TAG
419# define lisp_h_make_fixnum(n) \ 419# define lisp_h_make_fixnum(n) \
420 XIL ((EMACS_INT) (((EMACS_UINT) (n) << INTTYPEBITS) + Lisp_Int0)) 420 XIL ((EMACS_INT) (((EMACS_UINT) (n) << INTTYPEBITS) + Lisp_Int0))
421# define lisp_h_XFIXNAT(a) XFIXNUM (a) 421# define lisp_h_XFIXNUM_RAW(a) (XLI (a) >> INTTYPEBITS)
422# define lisp_h_XFIXNUM(a) (XLI (a) >> INTTYPEBITS)
423# define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) 422# define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
424#endif 423#endif
425 424
@@ -460,8 +459,7 @@ typedef EMACS_INT Lisp_Word;
460# define XHASH(a) lisp_h_XHASH (a) 459# define XHASH(a) lisp_h_XHASH (a)
461# if USE_LSB_TAG 460# if USE_LSB_TAG
462# define make_fixnum(n) lisp_h_make_fixnum (n) 461# define make_fixnum(n) lisp_h_make_fixnum (n)
463# define XFIXNAT(a) lisp_h_XFIXNAT (a) 462# define XFIXNUM_RAW(a) lisp_h_XFIXNUM_RAW (a)
464# define XFIXNUM(a) lisp_h_XFIXNUM (a)
465# define XTYPE(a) lisp_h_XTYPE (a) 463# define XTYPE(a) lisp_h_XTYPE (a)
466# endif 464# endif
467#endif 465#endif
@@ -1141,17 +1139,9 @@ INLINE Lisp_Object
1141} 1139}
1142 1140
1143INLINE EMACS_INT 1141INLINE EMACS_INT
1144(XFIXNUM) (Lisp_Object a) 1142(XFIXNUM_RAW) (Lisp_Object a)
1145{ 1143{
1146 return lisp_h_XFIXNUM (a); 1144 return lisp_h_XFIXNUM_RAW (a);
1147}
1148
1149INLINE EMACS_INT
1150(XFIXNAT) (Lisp_Object a)
1151{
1152 EMACS_INT n = lisp_h_XFIXNAT (a);
1153 eassume (0 <= n);
1154 return n;
1155} 1145}
1156 1146
1157#else /* ! USE_LSB_TAG */ 1147#else /* ! USE_LSB_TAG */
@@ -1179,9 +1169,11 @@ make_fixnum (EMACS_INT n)
1179 return XIL (n); 1169 return XIL (n);
1180} 1170}
1181 1171
1182/* Extract A's value as a signed integer. */ 1172/* Extract A's value as a signed integer. Unlike XFIXNUM, this works
1173 on any Lisp object, although the resulting integer is useful only
1174 for things like hashing when A is not a fixnum. */
1183INLINE EMACS_INT 1175INLINE EMACS_INT
1184XFIXNUM (Lisp_Object a) 1176XFIXNUM_RAW (Lisp_Object a)
1185{ 1177{
1186 EMACS_INT i = XLI (a); 1178 EMACS_INT i = XLI (a);
1187 if (! USE_LSB_TAG) 1179 if (! USE_LSB_TAG)
@@ -1192,31 +1184,36 @@ XFIXNUM (Lisp_Object a)
1192 return i >> INTTYPEBITS; 1184 return i >> INTTYPEBITS;
1193} 1185}
1194 1186
1195/* Like XFIXNUM (A), but may be faster. A must be nonnegative. 1187#endif /* ! USE_LSB_TAG */
1196 If ! USE_LSB_TAG, this takes advantage of the fact that Lisp 1188
1197 integers have zero-bits in their tags. */ 1189INLINE bool
1198INLINE EMACS_INT 1190(FIXNUMP) (Lisp_Object x)
1199XFIXNAT (Lisp_Object a)
1200{ 1191{
1201 EMACS_INT int0 = Lisp_Int0; 1192 return lisp_h_FIXNUMP (x);
1202 EMACS_INT n = USE_LSB_TAG ? XFIXNUM (a) : XLI (a) - (int0 << VALBITS);
1203 eassume (0 <= n);
1204 return n;
1205} 1193}
1206 1194
1207#endif /* ! USE_LSB_TAG */ 1195INLINE EMACS_INT
1196XFIXNUM (Lisp_Object a)
1197{
1198 eassume (FIXNUMP (a));
1199 return XFIXNUM_RAW (a);
1200}
1208 1201
1209/* Extract A's value as an unsigned integer in the range 0..INTMASK. */ 1202/* Extract A's value as an unsigned integer in the range 0..INTMASK. */
1210INLINE EMACS_UINT 1203INLINE EMACS_UINT
1211XUFIXNUM (Lisp_Object a) 1204XUFIXNUM_RAW (Lisp_Object a)
1212{ 1205{
1213 EMACS_UINT i = XLI (a); 1206 EMACS_UINT i = XLI (a);
1214 return USE_LSB_TAG ? i >> INTTYPEBITS : i & INTMASK; 1207 return USE_LSB_TAG ? i >> INTTYPEBITS : i & INTMASK;
1215} 1208}
1209INLINE EMACS_UINT
1210XUFIXNUM (Lisp_Object a)
1211{
1212 eassume (FIXNUMP (a));
1213 return XUFIXNUM_RAW (a);
1214}
1216 1215
1217/* Return A's hash, which is in the range 0..INTMASK. Although XHASH (A) == 1216/* Return A's hash, which is in the range 0..INTMASK. */
1218 XUFIXNUM (A) currently, XUFIXNUM should be applied only to fixnums. */
1219
1220INLINE EMACS_INT 1217INLINE EMACS_INT
1221(XHASH) (Lisp_Object a) 1218(XHASH) (Lisp_Object a)
1222{ 1219{
@@ -1261,12 +1258,6 @@ make_lisp_ptr (void *ptr, enum Lisp_Type type)
1261 return a; 1258 return a;
1262} 1259}
1263 1260
1264INLINE bool
1265(FIXNUMP) (Lisp_Object x)
1266{
1267 return lisp_h_FIXNUMP (x);
1268}
1269
1270#define XSETINT(a, b) ((a) = make_fixnum (b)) 1261#define XSETINT(a, b) ((a) = make_fixnum (b))
1271#define XSETFASTINT(a, b) ((a) = make_fixed_natnum (b)) 1262#define XSETFASTINT(a, b) ((a) = make_fixed_natnum (b))
1272#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons)) 1263#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
@@ -2832,6 +2823,16 @@ FIXNATP (Lisp_Object x)
2832{ 2823{
2833 return FIXNUMP (x) && 0 <= XFIXNUM (x); 2824 return FIXNUMP (x) && 0 <= XFIXNUM (x);
2834} 2825}
2826
2827/* Like XFIXNUM (A), but may be faster. A must be nonnegative. */
2828INLINE EMACS_INT
2829XFIXNAT (Lisp_Object a)
2830{
2831 eassume (FIXNATP (a));
2832 EMACS_INT int0 = Lisp_Int0;
2833 return USE_LSB_TAG ? XFIXNUM (a) : XLI (a) - (int0 << VALBITS);
2834}
2835
2835INLINE bool 2836INLINE bool
2836NUMBERP (Lisp_Object x) 2837NUMBERP (Lisp_Object x)
2837{ 2838{
diff --git a/src/process.c b/src/process.c
index 15d87cf6015..cab390c10c6 100644
--- a/src/process.c
+++ b/src/process.c
@@ -2675,7 +2675,7 @@ conv_lisp_to_sockaddr (int family, Lisp_Object address, struct sockaddr *sa, int
2675 for (i = 0; i < len; i++) 2675 for (i = 0; i < len; i++)
2676 if (FIXNUMP (p->contents[i])) 2676 if (FIXNUMP (p->contents[i]))
2677 { 2677 {
2678 int j = XFIXNAT (p->contents[i]) & 0xffff; 2678 int j = XFIXNUM (p->contents[i]) & 0xffff;
2679 ip6[i] = ntohs (j); 2679 ip6[i] = ntohs (j);
2680 } 2680 }
2681 sa->sa_family = family; 2681 sa->sa_family = family;
diff --git a/src/textprop.c b/src/textprop.c
index ae42c44185f..3026ec7e992 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -799,7 +799,7 @@ last valid position in OBJECT. */)
799 else 799 else
800 CHECK_FIXNUM_COERCE_MARKER (limit); 800 CHECK_FIXNUM_COERCE_MARKER (limit);
801 801
802 if (XFIXNAT (position) >= XFIXNAT (limit)) 802 if (XFIXNAT (position) >= XFIXNUM (limit))
803 { 803 {
804 position = limit; 804 position = limit;
805 if (XFIXNAT (position) > ZV) 805 if (XFIXNAT (position) > ZV)
@@ -881,16 +881,17 @@ first valid position in OBJECT. */)
881 else 881 else
882 CHECK_FIXNUM_COERCE_MARKER (limit); 882 CHECK_FIXNUM_COERCE_MARKER (limit);
883 883
884 if (XFIXNAT (position) <= XFIXNAT (limit)) 884 if (XFIXNUM (position) <= XFIXNUM (limit))
885 { 885 {
886 position = limit; 886 position = limit;
887 if (XFIXNAT (position) < BEGV) 887 if (XFIXNUM (position) < BEGV)
888 XSETFASTINT (position, BEGV); 888 XSETFASTINT (position, BEGV);
889 } 889 }
890 else 890 else
891 { 891 {
892 Lisp_Object initial_value 892 Lisp_Object initial_value
893 = Fget_char_property (make_fixnum (XFIXNAT (position) - 1), 893 = Fget_char_property (make_fixnum (XFIXNUM (position)
894 - (0 <= XFIXNUM (position))),
894 prop, object); 895 prop, object);
895 896
896 while (true) 897 while (true)
@@ -970,13 +971,13 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT. */)
970 next = next_interval (i); 971 next = next_interval (i);
971 972
972 while (next && intervals_equal (i, next) 973 while (next && intervals_equal (i, next)
973 && (NILP (limit) || next->position < XFIXNAT (limit))) 974 && (NILP (limit) || next->position < XFIXNUM (limit)))
974 next = next_interval (next); 975 next = next_interval (next);
975 976
976 if (!next 977 if (!next
977 || (next->position 978 || (next->position
978 >= (FIXNUMP (limit) 979 >= (FIXNUMP (limit)
979 ? XFIXNAT (limit) 980 ? XFIXNUM (limit)
980 : (STRINGP (object) 981 : (STRINGP (object)
981 ? SCHARS (object) 982 ? SCHARS (object)
982 : BUF_ZV (XBUFFER (object)))))) 983 : BUF_ZV (XBUFFER (object))))))
@@ -1019,13 +1020,13 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT. */)
1019 next = next_interval (i); 1020 next = next_interval (i);
1020 while (next 1021 while (next
1021 && EQ (here_val, textget (next->plist, prop)) 1022 && EQ (here_val, textget (next->plist, prop))
1022 && (NILP (limit) || next->position < XFIXNAT (limit))) 1023 && (NILP (limit) || next->position < XFIXNUM (limit)))
1023 next = next_interval (next); 1024 next = next_interval (next);
1024 1025
1025 if (!next 1026 if (!next
1026 || (next->position 1027 || (next->position
1027 >= (FIXNUMP (limit) 1028 >= (FIXNUMP (limit)
1028 ? XFIXNAT (limit) 1029 ? XFIXNUM (limit)
1029 : (STRINGP (object) 1030 : (STRINGP (object)
1030 ? SCHARS (object) 1031 ? SCHARS (object)
1031 : BUF_ZV (XBUFFER (object)))))) 1032 : BUF_ZV (XBUFFER (object))))))
@@ -1069,13 +1070,13 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT. */)
1069 previous = previous_interval (i); 1070 previous = previous_interval (i);
1070 while (previous && intervals_equal (previous, i) 1071 while (previous && intervals_equal (previous, i)
1071 && (NILP (limit) 1072 && (NILP (limit)
1072 || (previous->position + LENGTH (previous) > XFIXNAT (limit)))) 1073 || (previous->position + LENGTH (previous) > XFIXNUM (limit))))
1073 previous = previous_interval (previous); 1074 previous = previous_interval (previous);
1074 1075
1075 if (!previous 1076 if (!previous
1076 || (previous->position + LENGTH (previous) 1077 || (previous->position + LENGTH (previous)
1077 <= (FIXNUMP (limit) 1078 <= (FIXNUMP (limit)
1078 ? XFIXNAT (limit) 1079 ? XFIXNUM (limit)
1079 : (STRINGP (object) ? 0 : BUF_BEGV (XBUFFER (object)))))) 1080 : (STRINGP (object) ? 0 : BUF_BEGV (XBUFFER (object))))))
1080 return limit; 1081 return limit;
1081 else 1082 else
@@ -1122,13 +1123,13 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT. */)
1122 while (previous 1123 while (previous
1123 && EQ (here_val, textget (previous->plist, prop)) 1124 && EQ (here_val, textget (previous->plist, prop))
1124 && (NILP (limit) 1125 && (NILP (limit)
1125 || (previous->position + LENGTH (previous) > XFIXNAT (limit)))) 1126 || (previous->position + LENGTH (previous) > XFIXNUM (limit))))
1126 previous = previous_interval (previous); 1127 previous = previous_interval (previous);
1127 1128
1128 if (!previous 1129 if (!previous
1129 || (previous->position + LENGTH (previous) 1130 || (previous->position + LENGTH (previous)
1130 <= (FIXNUMP (limit) 1131 <= (FIXNUMP (limit)
1131 ? XFIXNAT (limit) 1132 ? XFIXNUM (limit)
1132 : (STRINGP (object) ? 0 : BUF_BEGV (XBUFFER (object)))))) 1133 : (STRINGP (object) ? 0 : BUF_BEGV (XBUFFER (object))))))
1133 return limit; 1134 return limit;
1134 else 1135 else
@@ -1353,8 +1354,8 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties,
1353 /* If we want no properties for a whole string, 1354 /* If we want no properties for a whole string,
1354 get rid of its intervals. */ 1355 get rid of its intervals. */
1355 if (NILP (properties) && STRINGP (object) 1356 if (NILP (properties) && STRINGP (object)
1356 && XFIXNAT (start) == 0 1357 && EQ (start, make_fixnum (0))
1357 && XFIXNAT (end) == SCHARS (object)) 1358 && EQ (end, make_fixnum (SCHARS (object))))
1358 { 1359 {
1359 if (!string_intervals (object)) 1360 if (!string_intervals (object))
1360 return Qnil; 1361 return Qnil;
diff --git a/src/w32term.c b/src/w32term.c
index 5726124b0ed..97a5fc63892 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -2464,7 +2464,7 @@ w32_draw_glyph_string (struct glyph_string *s)
2464 = buffer_local_value (Qunderline_minimum_offset, 2464 = buffer_local_value (Qunderline_minimum_offset,
2465 s->w->contents); 2465 s->w->contents);
2466 if (FIXNUMP (val)) 2466 if (FIXNUMP (val))
2467 minimum_offset = XFIXNAT (val); 2467 minimum_offset = max (0, XFIXNUM (val));
2468 else 2468 else
2469 minimum_offset = 1; 2469 minimum_offset = 1;
2470 val = buffer_local_value (Qx_underline_at_descent_line, 2470 val = buffer_local_value (Qx_underline_at_descent_line,
diff --git a/src/xterm.c b/src/xterm.c
index 1acff2af0da..38bc17de973 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3807,7 +3807,7 @@ x_draw_glyph_string (struct glyph_string *s)
3807 = buffer_local_value (Qunderline_minimum_offset, 3807 = buffer_local_value (Qunderline_minimum_offset,
3808 s->w->contents); 3808 s->w->contents);
3809 if (FIXNUMP (val)) 3809 if (FIXNUMP (val))
3810 minimum_offset = XFIXNAT (val); 3810 minimum_offset = max (0, XFIXNUM (val));
3811 else 3811 else
3812 minimum_offset = 1; 3812 minimum_offset = 1;
3813 val = buffer_local_value (Qx_underline_at_descent_line, 3813 val = buffer_local_value (Qx_underline_at_descent_line,