--- /dev/null
+Return-Path: <dme@dme.org>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id 7FA0E40DDD5\r
+ for <notmuch@notmuchmail.org>; Fri, 12 Nov 2010 04:52:04 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -1.9\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5\r
+ tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001] autolearn=ham\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id RKfDMg-cH8Df for <notmuch@notmuchmail.org>;\r
+ Fri, 12 Nov 2010 04:51:54 -0800 (PST)\r
+Received: from mail-ww0-f53.google.com (mail-ww0-f53.google.com\r
+ [74.125.82.53]) by olra.theworths.org (Postfix) with ESMTP id CC07440DDCF for\r
+ <notmuch@notmuchmail.org>; Fri, 12 Nov 2010 04:51:53 -0800 (PST)\r
+Received: by wwe15 with SMTP id 15so2321450wwe.34\r
+ for <notmuch@notmuchmail.org>; Fri, 12 Nov 2010 04:51:53 -0800 (PST)\r
+Received: by 10.216.24.206 with SMTP id x56mr2022490wex.2.1289566311213;\r
+ Fri, 12 Nov 2010 04:51:51 -0800 (PST)\r
+Received: from ut.hh.sledj.net (host81-149-164-25.in-addr.btopenworld.com\r
+ [81.149.164.25])\r
+ by mx.google.com with ESMTPS id y15sm2119092weq.6.2010.11.12.04.51.49\r
+ (version=TLSv1/SSLv3 cipher=RC4-MD5);\r
+ Fri, 12 Nov 2010 04:51:50 -0800 (PST)\r
+Received: by ut.hh.sledj.net (Postfix, from userid 1000)\r
+ id 2C25959405B; Fri, 12 Nov 2010 12:50:05 +0000 (GMT)\r
+From: David Edmondson <dme@dme.org>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH] emacs: Avoid regexp overflow when tidying citations.\r
+Date: Fri, 12 Nov 2010 12:50:02 +0000\r
+Message-Id: <1289566202-24148-1-git-send-email-dme@dme.org>\r
+X-Mailer: git-send-email 1.7.2.3\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Fri, 12 Nov 2010 12:52:04 -0000\r
+\r
+Declare `notmuch-wash-tidy-citations-max', which is the largest region\r
+that `notmuch-wash-tidy-citations' will attempt to improve.\r
+---\r
+ emacs/notmuch-wash.el | 61 ++++++++++++++++++++++++++++---------------------\r
+ 1 files changed, 35 insertions(+), 26 deletions(-)\r
+\r
+diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el\r
+index cfcfb21..a7ea5e9 100644\r
+--- a/emacs/notmuch-wash.el\r
++++ b/emacs/notmuch-wash.el\r
+@@ -187,6 +187,11 @@ is what to put on the button."\r
+ \r
+ ;;\r
+ \r
++(defcustom notmuch-wash-tidy-citations-max (* 10 1024)\r
++ "Maximum size of region to tidy."\r
++ :group 'notmuch\r
++ :type 'int)\r
++\r
+ (defun notmuch-wash-tidy-citations (depth)\r
+ "Improve the display of cited regions of a message.\r
+ \r
+@@ -199,32 +204,36 @@ Perform four transformations on the message body:\r
+ - Remove citation trailers standing alone after a block of cited\r
+ text."\r
+ \r
+- ;; Remove lines of repeated citation leaders with no other content.\r
+- (goto-char (point-min))\r
+- (while (re-search-forward "\\(^>[> ]*\n\\)\\{2,\\}" nil t)\r
+- (replace-match "\\1"))\r
+-\r
+- ;; Remove citation leaders standing alone before a block of cited\r
+- ;; text.\r
+- (goto-char (point-min))\r
+- (while (re-search-forward "\\(\n\\|^[^>].*\\)\n\\(^>[> ]*\n\\)" nil t)\r
+- (replace-match "\\1\n"))\r
+-\r
+- ;; Remove citation trailers standing alone after a block of cited\r
+- ;; text.\r
+- (goto-char (point-min))\r
+- (while (re-search-forward "\\(^>[> ]*\n\\)\\(^$\\|^[^>].*\\)" nil t)\r
+- (replace-match "\\2"))\r
+-\r
+- ;; Insert a blank line before a citation if there isn't one.\r
+- (goto-char (point-min))\r
+- (while (re-search-forward "\\(^[^>]+\\)\n>" nil t)\r
+- (replace-match "\\1\n\n>"))\r
+-\r
+- ;; Insert a blank line after a citation if there isn't one.\r
+- (goto-char (point-min))\r
+- (while (re-search-forward "\\(^>.+\\)\n\\([^>]\\)" nil t)\r
+- (replace-match "\\1\n\n\\2")))\r
++ ;; If the message is long, don't bother.\r
++ (unless (> (- (point-max) (point-min))\r
++ notmuch-wash-tidy-citations-max)\r
++\r
++ ;; Remove lines of repeated citation leaders with no other content.\r
++ (goto-char (point-min))\r
++ (while (re-search-forward "\\(^>[> ]*\n\\)\\{2,\\}" nil t)\r
++ (replace-match "\\1"))\r
++\r
++ ;; Remove citation leaders standing alone before a block of cited\r
++ ;; text.\r
++ (goto-char (point-min))\r
++ (while (re-search-forward "\\(\n\\|^[^>].*\\)\n\\(^>[> ]*\n\\)" nil t)\r
++ (replace-match "\\1\n"))\r
++\r
++ ;; Remove citation trailers standing alone after a block of cited\r
++ ;; text.\r
++ (goto-char (point-min))\r
++ (while (re-search-forward "\\(^>[> ]*\n\\)\\(^$\\|^[^>].*\\)" nil t)\r
++ (replace-match "\\2"))\r
++\r
++ ;; Insert a blank line before a citation if there isn't one.\r
++ (goto-char (point-min))\r
++ (while (re-search-forward "\\(^[^>]+\\)\n>" nil t)\r
++ (replace-match "\\1\n\n>"))\r
++\r
++ ;; Insert a blank line after a citation if there isn't one.\r
++ (goto-char (point-min))\r
++ (while (re-search-forward "\\(^>.+\\)\n\\([^>]\\)" nil t)\r
++ (replace-match "\\1\n\n\\2"))))\r
+ \r
+ ;;\r
+ \r
+-- \r
+1.7.2.3\r
+\r