From abf988ad69cc4e93419d43f1b86d463e16af594a Mon Sep 17 00:00:00 2001
From: Jean-Philippe Lang <jp_lang@yahoo.fr>
Date: Fri, 12 Nov 2010 13:08:32 +0000
Subject: [PATCH] Makes MailHandler ignore invalid keyword values to avoid
 validation failures.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4396 e93f8b46-1217-0410-a6f0-8f06a7374b81
---
 app/models/mail_handler.rb                    | 13 +++---
 .../ticket_with_invalid_attributes.eml        | 46 +++++++++++++++++++
 test/unit/mail_handler_test.rb                | 12 +++++
 3 files changed, 65 insertions(+), 6 deletions(-)
 create mode 100644 test/fixtures/mail_handler/ticket_with_invalid_attributes.eml

diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb
index 588dba81a..a5cf21f97 100644
--- a/app/models/mail_handler.rb
+++ b/app/models/mail_handler.rb
@@ -218,7 +218,7 @@ class MailHandler < ActionMailer::Base
       @keywords[attr]
     else
       @keywords[attr] = begin
-        if (options[:override] || @@handler_options[:allow_override].include?(attr.to_s)) && (v = extract_keyword!(plain_text_body, attr))
+        if (options[:override] || @@handler_options[:allow_override].include?(attr.to_s)) && (v = extract_keyword!(plain_text_body, attr, options[:format]))
           v
         elsif !@@handler_options[:issue][attr].blank?
           @@handler_options[:issue][attr]
@@ -229,7 +229,7 @@ class MailHandler < ActionMailer::Base
   
   # Destructively extracts the value for +attr+ in +text+
   # Returns nil if no matching keyword found
-  def extract_keyword!(text, attr)
+  def extract_keyword!(text, attr, format=nil)
     keys = [attr.to_s.humanize]
     if attr.is_a?(Symbol)
       keys << l("field_#{attr}", :default => '', :locale =>  user.language) if user
@@ -237,7 +237,8 @@ class MailHandler < ActionMailer::Base
     end
     keys.reject! {|k| k.blank?}
     keys.collect! {|k| Regexp.escape(k)}
-    text.gsub!(/^(#{keys.join('|')})[ \t]*:[ \t]*(.+)\s*$/i, '')
+    format ||= '.+'
+    text.gsub!(/^(#{keys.join('|')})[ \t]*:[ \t]*(#{format})\s*$/i, '')
     $2 && $2.strip
   end
 
@@ -259,10 +260,10 @@ class MailHandler < ActionMailer::Base
       'category_id' => (k = get_keyword(:category)) && issue.project.issue_categories.find_by_name(k).try(:id),
       'assigned_to_id' => (k = get_keyword(:assigned_to, :override => true)) && find_user_from_keyword(k).try(:id),
       'fixed_version_id' => (k = get_keyword(:fixed_version, :override => true)) && issue.project.shared_versions.find_by_name(k).try(:id),
-      'start_date' => get_keyword(:start_date, :override => true),
-      'due_date' => get_keyword(:due_date, :override => true),
+      'start_date' => get_keyword(:start_date, :override => true, :format => '\d{4}-\d{2}-\d{2}'),
+      'due_date' => get_keyword(:due_date, :override => true, :format => '\d{4}-\d{2}-\d{2}'),
       'estimated_hours' => get_keyword(:estimated_hours, :override => true),
-      'done_ratio' => get_keyword(:done_ratio, :override => true),
+      'done_ratio' => get_keyword(:done_ratio, :override => true, :format => '(\d|10)?0')
     }.delete_if {|k, v| v.blank? }
   end
   
diff --git a/test/fixtures/mail_handler/ticket_with_invalid_attributes.eml b/test/fixtures/mail_handler/ticket_with_invalid_attributes.eml
new file mode 100644
index 000000000..3b39fb551
--- /dev/null
+++ b/test/fixtures/mail_handler/ticket_with_invalid_attributes.eml
@@ -0,0 +1,46 @@
+Return-Path: <jsmith@somenet.foo>
+Received: from osiris ([127.0.0.1])
+	by OSIRIS
+	with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
+Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
+From: "John Smith" <jsmith@somenet.foo>
+To: <redmine@somenet.foo>
+Subject: New ticket on a given project
+Date: Sun, 22 Jun 2008 12:28:07 +0200
+MIME-Version: 1.0
+Content-Type: text/plain;
+	format=flowed;
+	charset="iso-8859-1";
+	reply-type=original
+Content-Transfer-Encoding: 7bit
+X-Priority: 3
+X-MSMail-Priority: Normal
+X-Mailer: Microsoft Outlook Express 6.00.2900.2869
+X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
+
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet 
+turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus 
+blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti 
+sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In 
+in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras 
+sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum 
+id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus 
+eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique 
+sed, mauris. Pellentesque habitant morbi tristique senectus et netus et 
+malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse 
+platea dictumst.
+
+Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque 
+sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem. 
+Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et, 
+dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed, 
+massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo 
+pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
+
+Project: onlinestore
+Tracker: Feature request
+category: Stock management
+priority: foo
+done ratio: x
+start date: some day 
+due date: never
diff --git a/test/unit/mail_handler_test.rb b/test/unit/mail_handler_test.rb
index 74a06f61c..65b0409bb 100644
--- a/test/unit/mail_handler_test.rb
+++ b/test/unit/mail_handler_test.rb
@@ -229,6 +229,18 @@ class MailHandlerTest < ActiveSupport::TestCase
     assert_equal false, submit_email('ticket_without_from_header.eml')
   end
 
+  def test_add_issue_with_invalid_attributes
+    issue = submit_email('ticket_with_invalid_attributes.eml', :allow_override => 'tracker,category,priority')
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_nil issue.start_date
+    assert_nil issue.due_date
+    assert_equal 0, issue.done_ratio
+    assert_equal 'Normal', issue.priority.to_s
+    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
+  end
+
   def test_add_issue_with_localized_attributes
     User.find_by_mail('jsmith@somenet.foo').update_attribute 'language', 'fr'
     issue = submit_email('ticket_with_localized_attributes.eml', :allow_override => 'tracker,category,priority')
-- 
GitLab