From a6727897392003115d2173baa152cd23eaf1ced6 Mon Sep 17 00:00:00 2001 From: naruse Date: Mon, 23 Jun 2014 20:01:27 +0000 Subject: [PATCH] * lib/uri/mailto.rb: support RFC6068. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46528 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 4 +++ lib/uri/mailto.rb | 65 ++++++++++++++--------------------------- test/uri/test_mailto.rb | 5 +--- 3 files changed, 27 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index a0feda9eb7..fecacc5df4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Tue Jun 24 03:52:35 2014 NARUSE, Yui + + * lib/uri/mailto.rb: support RFC6068. + Mon Jun 23 18:44:45 2014 SHIBATA Hiroshi * tool/config_files.rb: rename class ConfigFiles to Downloader. diff --git a/lib/uri/mailto.rb b/lib/uri/mailto.rb index 03155fb917..6422e84f37 100644 --- a/lib/uri/mailto.rb +++ b/lib/uri/mailto.rb @@ -12,7 +12,7 @@ require 'uri/generic' module URI # - # RFC2368, The mailto URL scheme + # RFC6068, The mailto URL scheme # class MailTo < Generic include REGEXP @@ -37,28 +37,12 @@ module URI # # Within mailto URLs, the characters "?", "=", "&" are reserved. - # hname = *urlc - # hvalue = *urlc - # header = hname "=" hvalue - HEADER_PATTERN = "(?:[^?=&]*=[^?=&]*)".freeze - HEADER_REGEXP = Regexp.new(HEADER_PATTERN).freeze + HEADER_REGEXP = /\A(?(?:%\h\h|[!$'-.0-;@-Z_a-z~])*=(?:%\h\h|[!$'-.0-;@-Z_a-z~])*)(?:&\g)*\z/ # headers = "?" header *( "&" header ) - # to = #mailbox - # mailtoURL = "mailto:" [ to ] [ headers ] - MAILBOX_PATTERN = "(?:#{PATTERN::ESCAPED}|[^(),%?=&])".freeze - MAILTO_REGEXP = Regexp.new(" # :nodoc: - \\A - (#{MAILBOX_PATTERN}*?) (?# 1: to) - (?: - \\? - (#{HEADER_PATTERN}(?:\\&#{HEADER_PATTERN})*) (?# 2: headers) - )? - (?: - \\# - (#{PATTERN::FRAGMENT}) (?# 3: fragment) - )? - \\z - ", Regexp::EXTENDED).freeze + # to = addr-spec *("," addr-spec ) + # mailtoURI = "mailto:" [ to ] [ hfields ] + TO_REGEXP = /\A(?:[!#-'*+\-\/-9=?A-Z^-~]+(?:\.[!#-'*+\-\/-9=?A-Z^-~]+)*|"(?:\\[!-~]|[!#-\[\]-~])*")@(?:[!#-'*+\-\/-9=?A-Z^-~]+(?:\.[!#-'*+\-\/-9=?A-Z^-~]+)*|\[[!-Z^-~]*\])\z/ + MAILTO_DATA_REGEXP = /\A(?(?(?[!#-'*+\-\/-9=?A-Z^-~]+(?:\.[!#-'*+\-\/-9=?A-Z^-~]+)*|"(?:\\[!-~]|[!#-\[\]-~])*")@(?[!#-'*+\-\/-9=?A-Z^-~]+(?:\.[!#-'*+\-\/-9=?A-Z^-~]+)*|\[[!-Z^-~]*\]))(?:,\g)*)?(?\?(?
(?(?:%\h\h|[!$'-.0-;@-Z_a-z~])*=(?:%\h\h|[!$'-.0-;@-Z_a-z~])*)(?:&\g)*))?\z/ # :startdoc: # @@ -99,8 +83,8 @@ module URI if tmp[:headers] tmp[:opaque] << '?' - - if tmp[:headers].kind_of?(Array) + case tmp[:headers] + when Array tmp[:opaque] << tmp[:headers].collect { |x| if x.kind_of?(Array) x[0] + '=' + x[1..-1].join @@ -108,12 +92,10 @@ module URI x.to_s end }.join('&') - - elsif tmp[:headers].kind_of?(Hash) + when Hash tmp[:opaque] << tmp[:headers].collect { |h,v| h + '=' + v }.join('&') - else tmp[:opaque] << tmp[:headers].to_s end @@ -137,13 +119,13 @@ module URI @to = nil @headers = [] - if MAILTO_REGEXP =~ @opaque + if m = MAILTO_DATA_REGEXP.match(@opaque) if arg[10] # arg_check - self.to = $1 - self.headers = $2 + self.to = m["to"] + self.headers = m["header"] else - set_to($1) - set_headers($2) + set_to(m["to"]) + set_headers(m["header"]) end else @@ -158,14 +140,12 @@ module URI # E-mail headers set by the URL, as an Array of Arrays attr_reader :headers - # check the to +v+ component against either - # * URI::Parser Regexp for :OPAQUE - # * MAILBOX_PATTERN + # check the to +v+ component def check_to(v) return true unless v return true if v.size == 0 - if parser.regexp[:OPAQUE] !~ v || /\A#{MAILBOX_PATTERN}*\z/o !~ v + if TO_REGEXP !~ v raise InvalidComponentError, "bad component(expected opaque component): #{v}" end @@ -188,14 +168,13 @@ module URI end # check the headers +v+ component against either - # * URI::Parser Regexp for :OPAQUE - # * HEADER_PATTERN + # * URI::Parser Regexp for :QUERY + # * HEADER_REGEXP def check_headers(v) return true unless v return true if v.size == 0 - - if parser.regexp[:OPAQUE] !~ v || - /\A(#{HEADER_PATTERN}(?:\&#{HEADER_PATTERN})*)\z/o !~ v + if parser.regexp[:QUERY] !~ v || + HEADER_REGEXP !~ v raise InvalidComponentError, "bad component(expected opaque component): #{v}" end @@ -208,8 +187,8 @@ module URI def set_headers(v) @headers = [] if v - v.scan(HEADER_REGEXP) do |x| - @headers << x.split(/=/o, 2) + v.split('&').each do |x| + @headers << x.split(/=/, 2) end end end diff --git a/test/uri/test_mailto.rb b/test/uri/test_mailto.rb index c2158845e8..3aac447436 100644 --- a/test/uri/test_mailto.rb +++ b/test/uri/test_mailto.rb @@ -100,9 +100,6 @@ class TestMailTo < Test::Unit::TestCase # mailto:javascript:alert() bad << ["javascript:alert()", []] - # '=' which is in hname or hvalue is wrong. - bad << ["foo@example.jp?subject=1+1=2", []] - ok.each do |x| assert_equal(x[0], @u.build(x[1]).to_s) @@ -111,7 +108,7 @@ class TestMailTo < Test::Unit::TestCase end bad.each do |x| - assert_raise(URI::InvalidComponentError) { + assert_raise(URI::InvalidComponentError, %[URI::MailTo.build(#{x.inspect})]) { @u.build(x) } end