Subject: Broken matching of regexps in fancy splitting

From: jathd <[email-masked]>
Date: Fri, 07 Sep 2012 05:41:45 +0200

Hi.

I'm not sure if this counts as a bug, but it's certainly an unexpected
behaviour (to me) to which I have found no reference in the manual.

The situation:

 * In .gnus.el, specify splitting with
    
       (setq nnmail-split-methods 'nnmail-split-fancy)
       (setq nnmail-split-fancy
             '(to "\\(\\w+\\)-devel@.*" "list.devel.\\1"))

 * Visit a message whose only relevant header (relative to the "to"
   abbreviation) is

       To: Batteries-devel <[email-masked]>
   
 * Press B q and read the message in the minibuffer.

Current message: This message would go to list.devel.s
Expected message: This message would go to list.devel.batteries

I believe the problem comes from the way the regexp value I gave (the
VALUE field in the split) is matched against the contents of the header,
as defined in the function nnmail-split-it in nnmail.el. Once the
interesting bit of the header has been found, the match is done with
re-search-backward, which explains why the "\\w+" bit only matches the
last letter of "batteries".

This conflicts with what is usually meant by a regexp matching a
string. I know I was expecting the match to be done as if by
(string-match regexp relevant-header-part). Here's a simple patch that
changes re-search-backward to re-search-forward:

========================================================================
--- a/lisp/nnmail.el
+++ b/lisp/nnmail.el
@@ -1463,13 +1463,13 @@ See the documentation for the variable `nnmail-split-fancy' for details."
 		  (setq split-rest nil)
 		(setq split-rest (cddr split-rest))))
 	    (when split-rest
-	      (goto-char end)
+	      (goto-char start-of-value)
 	      (let ((value (nth 1 split)))
 		(if (symbolp value)
 		    (setq value (cdr (assq value nnmail-split-abbrev-alist))))
 		;; Someone might want to do a \N sub on this match, so get the
 		;; correct match positions.
-		(re-search-backward value start-of-value))
+		(re-search-forward value end))
 	      (dolist (sp (nnmail-split-it (car split-rest)))
 		(unless (member sp split-result)
 		  (push sp split-result))))))
========================================================================

This produces the expected message, and I don't think it should break
anything.

[As a side note: is there a particular reason why the file nnmail.el
uses re-search-backward everywhere and not re-search-forward, or does it
come down to taste?]

Ma Gnus v0.6
GNU Emacs 24.2.50.1 (x86_64-apple-darwin10.8.0, NS apple-appkit-1038.36)
 of 2012-09-07 on mbk.local
200 news-1.free.fr (5-1) NNRP Service Ready - [email-masked] (posting ok)
500 What?

-- 
jathd