From de00a933e4b35b42398582eaba58531e5fdd46ca Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 27 Mar 2020 00:58:31 -0700 Subject: Treat out-of-range positions consistently If a position argument to get-byte etc. is an out-of-range integer, treat it the same regardless of whether it is a fixnum or a bignum. * src/buffer.c (fix_position): New function. * src/buffer.c (validate_region): * src/character.c (Fget_byte): * src/coding.c (Ffind_coding_systems_region_internal) (Fcheck_coding_systems_region): * src/composite.c (Ffind_composition_internal): * src/editfns.c (Fposition_bytes, Fchar_after, Fchar_before) (Finsert_buffer_substring, Fcompare_buffer_substrings) (Fnarrow_to_region): * src/fns.c (Fsecure_hash_algorithms): * src/font.c (Finternal_char_font, Ffont_at): * src/fringe.c (Ffringe_bitmaps_at_pos): * src/search.c (search_command): * src/textprop.c (get_char_property_and_overlay): * src/window.c (Fpos_visible_in_window_p): * src/xdisp.c (Fwindow_text_pixel_size): Use it instead of CHECK_FIXNUM_COERCE_MARKER, so that the code is simpler and treats bignums consistently with fixnums. * src/buffer.h (CHECK_FIXNUM_COERCE_MARKER): Define here rather than in lisp.h, and reimplement in terms of fix_position so that it treats bignums consistently with fixnums. * src/lisp.h (CHECK_FIXNUM_COERCE_MARKER): Move to buffer.h. * src/textprop.c (validate_interval_range): Signal with original bounds rather than modified ones. --- src/buffer.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index cc7d4e4817c..70598a7a22a 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -131,6 +131,23 @@ CHECK_OVERLAY (Lisp_Object x) CHECK_TYPE (OVERLAYP (x), Qoverlayp, x); } +/* Convert the position POS to an EMACS_INT that fits in a fixnum. + Yield POS's value if POS is already a fixnum, POS's marker position + if POS is a marker, and MOST_NEGATIVE_FIXNUM or + MOST_POSITIVE_FIXNUM if POS is a negative or positive bignum. + Signal an error if POS is not of the proper form. */ + +EMACS_INT +fix_position (Lisp_Object pos) +{ + if (FIXNUMP (pos)) + return XFIXNUM (pos); + if (MARKERP (pos)) + return marker_position (pos); + CHECK_TYPE (BIGNUMP (pos), Qinteger_or_marker_p, pos); + return !NILP (Fnatnump (pos)) ? MOST_POSITIVE_FIXNUM : MOST_NEGATIVE_FIXNUM; +} + /* These setters are used only in this file, so they can be private. The public setters are inline functions defined in buffer.h. */ static void @@ -2257,19 +2274,20 @@ so the buffer is truly empty after this. */) } void -validate_region (register Lisp_Object *b, register Lisp_Object *e) +validate_region (Lisp_Object *b, Lisp_Object *e) { - CHECK_FIXNUM_COERCE_MARKER (*b); - CHECK_FIXNUM_COERCE_MARKER (*e); + EMACS_INT beg = fix_position (*b), end = fix_position (*e); - if (XFIXNUM (*b) > XFIXNUM (*e)) + if (end < beg) { - Lisp_Object tem; - tem = *b; *b = *e; *e = tem; + EMACS_INT tem = beg; beg = end; end = tem; } - if (! (BEGV <= XFIXNUM (*b) && XFIXNUM (*e) <= ZV)) + if (! (BEGV <= beg && end <= ZV)) args_out_of_range_3 (Fcurrent_buffer (), *b, *e); + + *b = make_fixnum (beg); + *e = make_fixnum (end); } /* Advance BYTE_POS up to a character boundary -- cgit v1.2.1