Subject: bug#21615: 24.5; font-lock-extend-region-wholelines' infinite loop

From: [email-masked]
Date: Sun, 04 Oct 2015 19:34:07 +0200

The function `font-lock-extend-region-wholelines' uses `bolp' to check
if point is at the beginning of the line, and, if not, it calls
`line-beginning-position' to move to the beginning of the line.

Here is the code from `font-lock-extend-region-wholelines':

,----
| (goto-char font-lock-beg)
| (unless (bolp)
|   (setq changed t font-lock-beg (line-beginning-position)))
`----

But, `line-beginning-position' moves to the beginning of the line *OR*
to the beginning of a *field*. Thus, if point is at the beginning of a
field that is not at the beginning of a line, `changed' is set to t but
the region is not changed. As `font-lock-extend-region-wholelines' is
called again until it doesn't signal a change, we end up in an infinite
loop.

To reproduce, use the attached file and run it like that:

,----
| emacs -Q --file test-font-lock-infloop.el --eval '(progn (eval-buffer) (DO-NOT-EVAL-ME))'
`----

Bruno.

In GNU Emacs 24.5.1 (x86_64-pc-linux-gnu, GTK+ Version 3.14.9)
 of 2015-09-22 on tosh-laptop
Windowing system distributor `The X.Org Foundation', version 11.0.11502000
Configured using:
 `configure --prefix=/usr --build=x86_64-pc-linux-gnu
 --host=x86_64-pc-linux-gnu --mandir=/usr/share/man
 --infodir=/usr/share/info --datadir=/usr/share --sysconfdir=/etc
 --localstatedir=/var/lib --disable-dependency-tracking
 --disable-silent-rules --libdir=/usr/lib64 --program-suffix=-emacs-24
 --infodir=/usr/share/info/emacs-24 --localstatedir=/var
 --enable-locallisppath=/etc/emacs:/usr/share/emacs/site-lisp
 --with-gameuser=:gamestat --without-compress-install
 --with-file-notification=inotify --enable-acl --with-dbus
 --without-gnutls --without-gpm --without-hesiod --without-kerberos
 --without-kerberos5 --with-xml2 --without-selinux --without-wide-int
 --with-zlib --with-sound=alsa --with-x --without-ns --without-gconf
 --without-gsettings --without-toolkit-scroll-bars --without-gif
 --with-jpeg --with-png --with-rsvg --without-tiff --with-xpm
 --with-imagemagick --with-xft --without-libotf --without-m17n-flt
 --with-x-toolkit=gtk3 GENTOO_PACKAGE=app-editors/emacs-24.5 'CFLAGS=-O2
 -pipe -march=native' CPPFLAGS= 'LDFLAGS=-Wl,-O1 -Wl,--as-needed''

Important settings:
  value of $LC_CTYPE: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  tooltip-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent messages:
For information about GNU Emacs and the GNU system, type C-h C-a.
Quit
current-kill: Kill ring is empty
delete-backward-char: Text is read-only

Load-path shadows:
None found.

Features:
(shadow sort gnus-util mail-extr emacsbug message format-spec rfc822 mml
easymenu mml-sec mm-decode mm-bodies mm-encode mail-parse rfc2231
mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums
mm-util help-fns mail-prsvr mail-utils time-date tooltip electric
uniquify ediff-hook vc-hooks lisp-float-type mwheel x-win x-dnd tool-bar
dnd fontset image regexp-opt fringe tabulated-list newcomment lisp-mode
prog-mode register page menu-bar rfn-eshadow timer select scroll-bar
mouse jit-lock font-lock syntax facemenu font-core frame cham georgian
utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese case-table epa-hook jka-cmpr-hook help simple abbrev
minibuffer nadvice loaddefs button faces cus-face macroexp files
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget hashtable-print-readable backquote make-network-process
dbusbind inotify dynamic-setting font-render-setting move-toolbar gtk
x-toolkit x multi-tty emacs)

Memory information:
((conses 16 71404 9137)
 (symbols 48 17534 0)
 (miscs 40 37 138)
 (strings 32 9208 4463)
 (string-bytes 1 253754)
 (vectors 16 8909)
 (vector-slots 8 383166 18279)
 (floats 8 63 99)
 (intervals 56 222 10)
 (buffers 960 11)
 (heap 1024 24783 718))

===File
/home/bruno/WorkingDirectory/Community/Emacs/Gnu-Emacs/test-font-lock-infloop.el===
(defun DO-NOT-EVAL-ME ()
  "FREEZE YOUR EMACS.

DO NOT RUN IN YOUR MAIN EMACS.

Run this file as follows:

   emacs -Q --file test-font-lock-infloop.el --eval '(progn (eval-buffer) (DO-NOT-EVAL-ME))'

Then, type something between \"TYPE HERE==>>>\" and \"<<<==TYPE HERE\".

Your Emacs should now hangs.
    
GNU Emacs 24.5.1 (x86_64-pc-linux-gnu, GTK+ Version 3.14.9)
But should work with any Emacs."

  ;; Publish our own custom function to extend the region to fontify.
  ;; 
  ;;    The first function can say whatever it wants (changed=t or
  ;;    nil), it's ignored. Thus, we need to push
  ;;    `font-lock-extend-region-wholelines' into the second position
  ;;    to show the bug.
  ;;    
  (add-hook 'font-lock-extend-region-functions
	    (lambda () :whatever))

  ;; Put a 'field property between the two "TYPE HERE" below.
  ;; Typing there will make Emacs hangs ... well, if not before.
  ;;     
  (let ((beg (re-search-forward "TYPE HERE==>>>"))
	(end (re-search-forward "<<<==TYPE HERE"))
	)
    (add-text-properties beg end '(field :hang front-sticky t))
    ))

(DO-NOT-EVAL-ME)

;; TYPE HERE==>>>          <<<==TYPE HERE
============================================================