rails_autolink 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile CHANGED
@@ -1,8 +1,8 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
- gem 'rails', :path => '/Users/aaron/git/rails'
4
- gem 'arel', :path => '/Users/aaron/git/arel'
5
- gem 'rack', :path => '/Users/aaron/git/rack'
3
+ gem 'rails'
4
+ gem 'arel'
5
+ gem 'rack'
6
6
  gem 'hoe'
7
7
  gem 'minitest'
8
8
 
@@ -8,9 +8,11 @@ This is an extraction of the `auto_link` method from rails. The `auto_link`
8
8
  method was removed from Rails in version Rails 3.1. This gem is meant to
9
9
  bridge the gap for people migrating.
10
10
 
11
- == FEATURES/PROBLEMS:
11
+ == FEATURES:
12
12
 
13
- * May not be safe!
13
+ By default auto_link returns sanitized html_safe strings.
14
+ This behaviour can be overriden setting the <tt>:sanitize</tt> option to false
15
+ (thus making it insecure if you don't have the content under control).
14
16
 
15
17
  == SYNOPSIS:
16
18
 
@@ -27,6 +29,12 @@ bridge the gap for people migrating.
27
29
  auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :email_addresses)
28
30
  # => "Visit http://www.loudthinking.com/ or e-mail <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"
29
31
 
32
+ auto_link("Go to http://www.rubyonrails.org <script>Malicious code!</script>")
33
+ # => "Go to <a href=\"http://www.rubyonrails.org\">http://www.rubyonrails.org</a> "
34
+
35
+ auto_link("Go to http://www.rubyonrails.org <script>alert('Script!')</script>", :sanitize => false)
36
+ # => "Go to <a href=\"http://www.rubyonrails.org\">http://www.rubyonrails.org</a> <script>alert('Script!')</script>"
37
+
30
38
  post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
31
39
  auto_link(post_body, :html => { :target => '_blank' }) do |text|
32
40
  truncate(text, :length => 15)
@@ -35,11 +43,11 @@ bridge the gap for people migrating.
35
43
 
36
44
  == REQUIREMENTS:
37
45
 
38
- * rails
46
+ * rails >= 3.1
39
47
 
40
48
  == INSTALL:
41
49
 
42
- * gem install rails
50
+ * gem install rails_autolink
43
51
 
44
52
  == LICENSE:
45
53
 
data/Rakefile CHANGED
@@ -13,7 +13,7 @@ Hoe.spec 'rails_autolink' do
13
13
  self.readme_file = 'README.rdoc'
14
14
  self.history_file = 'CHANGELOG.rdoc'
15
15
  self.extra_rdoc_files = FileList['*.rdoc']
16
- self.extra_deps << ['rails', '~> 3.1.0']
16
+ self.extra_deps << ['rails', '~> 3.1.0.a']
17
17
  end
18
18
 
19
19
  # vim: syntax=ruby
@@ -1,141 +1,149 @@
1
- require 'active_support/core_ext/object/blank'
2
- require 'active_support/core_ext/array/extract_options'
3
- require 'active_support/core_ext/hash/reverse_merge'
4
- require 'active_support/core_ext/hash/keys'
5
-
6
1
  module RailsAutolink
7
- VERSION = '1.0.0'
8
- end
9
-
10
- module ActionView
11
- module Helpers # :nodoc:
12
- module TextHelper
13
- # Turns all URLs and e-mail addresses into clickable links. The <tt>:link</tt> option
14
- # will limit what should be linked. You can add HTML attributes to the links using
15
- # <tt>:html</tt>. Possible values for <tt>:link</tt> are <tt>:all</tt> (default),
16
- # <tt>:email_addresses</tt>, and <tt>:urls</tt>. If a block is given, each URL and
17
- # e-mail address is yielded and the result is used as the link text.
18
- #
19
- # ==== Examples
20
- # auto_link("Go to http://www.rubyonrails.org and say hello to david@loudthinking.com")
21
- # # => "Go to <a href=\"http://www.rubyonrails.org\">http://www.rubyonrails.org</a> and
22
- # # say hello to <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"
23
- #
24
- # auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :urls)
25
- # # => "Visit <a href=\"http://www.loudthinking.com/\">http://www.loudthinking.com/</a>
26
- # # or e-mail david@loudthinking.com"
27
- #
28
- # auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :email_addresses)
29
- # # => "Visit http://www.loudthinking.com/ or e-mail <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"
30
- #
31
- # post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
32
- # auto_link(post_body, :html => { :target => '_blank' }) do |text|
33
- # truncate(text, :length => 15)
34
- # end
35
- # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.m...</a>.
36
- # Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."
37
- #
38
- #
39
- # You can still use <tt>auto_link</tt> with the old API that accepts the
40
- # +link+ as its optional second parameter and the +html_options+ hash
41
- # as its optional third parameter:
42
- # post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
43
- # auto_link(post_body, :urls)
44
- # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\">http://www.myblog.com</a>.
45
- # Please e-mail me at me@email.com."
46
- #
47
- # auto_link(post_body, :all, :target => "_blank")
48
- # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.myblog.com</a>.
49
- # Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."
50
- def auto_link(text, *args, &block)#link = :all, html = {}, &block)
51
- return '' if text.blank?
52
-
53
- options = args.size == 2 ? {} : args.extract_options! # this is necessary because the old auto_link API has a Hash as its last parameter
54
- unless args.empty?
55
- options[:link] = args[0] || :all
56
- options[:html] = args[1] || {}
57
- end
58
- options.reverse_merge!(:link => :all, :html => {})
59
-
60
- case options[:link].to_sym
61
- when :all then auto_link_email_addresses(auto_link_urls(text, options[:html], options, &block), options[:html], &block)
62
- when :email_addresses then auto_link_email_addresses(text, options[:html], &block)
63
- when :urls then auto_link_urls(text, options[:html], options, &block)
64
- end
65
- end
66
-
67
- private
68
-
69
- AUTO_LINK_RE = %r{
70
- (?: ([0-9A-Za-z+.:-]+:)// | www\. )
71
- [^\s<]+
72
- }x
73
-
74
- # regexps for determining context, used high-volume
75
- AUTO_LINK_CRE = [/<[^>]+$/, /^[^>]*>/, /<a\b.*?>/i, /<\/a>/i]
76
-
77
- AUTO_EMAIL_RE = /[\w.!#\$%+-]+@[\w-]+(?:\.[\w-]+)+/
78
-
79
- BRACKETS = { ']' => '[', ')' => '(', '}' => '{' }
80
-
81
- # Turns all urls into clickable links. If a block is given, each url
82
- # is yielded and the result is used as the link text.
83
- def auto_link_urls(text, html_options = {}, options = {})
84
- link_attributes = html_options.stringify_keys
85
- text.gsub(AUTO_LINK_RE) do
86
- scheme, href = $1, $&
87
- punctuation = []
88
-
89
- if auto_linked?($`, $')
90
- # do not change string; URL is already linked
91
- href
92
- else
93
- # don't include trailing punctuation character as part of the URL
94
- while href.sub!(/[^\w\/-]$/, '')
95
- punctuation.push $&
96
- if opening = BRACKETS[punctuation.last] and href.scan(opening).size > href.scan(punctuation.last).size
97
- href << punctuation.pop
98
- break
2
+ VERSION = '1.0.1'
3
+
4
+ class Railtie < ::Rails::Railtie
5
+ initializer 'nested_form' do |app|
6
+ ActiveSupport.on_load(:action_view) do
7
+ require 'active_support/core_ext/object/blank'
8
+ require 'active_support/core_ext/array/extract_options'
9
+ require 'active_support/core_ext/hash/reverse_merge'
10
+ require 'active_support/core_ext/hash/keys'
11
+
12
+ module ::ActionView
13
+ module Helpers # :nodoc:
14
+ module TextHelper
15
+ # Turns all URLs and e-mail addresses into clickable links. The <tt>:link</tt> option
16
+ # will limit what should be linked. You can add HTML attributes to the links using
17
+ # <tt>:html</tt>. Possible values for <tt>:link</tt> are <tt>:all</tt> (default),
18
+ # <tt>:email_addresses</tt>, and <tt>:urls</tt>. If a block is given, each URL and
19
+ # e-mail address is yielded and the result is used as the link text. By default the
20
+ # text given is sanitized, you can override this behaviour setting the
21
+ # <tt>:sanitize</tt> option to false.
22
+ #
23
+ # ==== Examples
24
+ # auto_link("Go to http://www.rubyonrails.org and say hello to david@loudthinking.com")
25
+ # # => "Go to <a href=\"http://www.rubyonrails.org\">http://www.rubyonrails.org</a> and
26
+ # # say hello to <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"
27
+ #
28
+ # auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :urls)
29
+ # # => "Visit <a href=\"http://www.loudthinking.com/\">http://www.loudthinking.com/</a>
30
+ # # or e-mail david@loudthinking.com"
31
+ #
32
+ # auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :email_addresses)
33
+ # # => "Visit http://www.loudthinking.com/ or e-mail <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"
34
+ #
35
+ # post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
36
+ # auto_link(post_body, :html => { :target => '_blank' }) do |text|
37
+ # truncate(text, :length => 15)
38
+ # end
39
+ # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.m...</a>.
40
+ # Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."
41
+ #
42
+ #
43
+ # You can still use <tt>auto_link</tt> with the old API that accepts the
44
+ # +link+ as its optional second parameter and the +html_options+ hash
45
+ # as its optional third parameter:
46
+ # post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
47
+ # auto_link(post_body, :urls)
48
+ # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\">http://www.myblog.com</a>.
49
+ # Please e-mail me at me@email.com."
50
+ #
51
+ # auto_link(post_body, :all, :target => "_blank")
52
+ # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.myblog.com</a>.
53
+ # Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."
54
+ def auto_link(text, *args, &block)#link = :all, html = {}, &block)
55
+ return ''.html_safe if text.blank?
56
+
57
+ options = args.size == 2 ? {} : args.extract_options! # this is necessary because the old auto_link API has a Hash as its last parameter
58
+ unless args.empty?
59
+ options[:link] = args[0] || :all
60
+ options[:html] = args[1] || {}
61
+ end
62
+ options.reverse_merge!(:link => :all, :html => {})
63
+ text = sanitize(text) unless options[:sanitize] == false
64
+ case options[:link].to_sym
65
+ when :all then auto_link_email_addresses(auto_link_urls(text, options[:html], options, &block), options[:html], &block)
66
+ when :email_addresses then auto_link_email_addresses(text, options[:html], &block)
67
+ when :urls then auto_link_urls(text, options[:html], options, &block)
99
68
  end
100
69
  end
101
70
 
102
- link_text = block_given?? yield(href) : href
103
- href = 'http://' + href unless scheme
104
-
105
- unless options[:sanitize] == false
106
- link_text = sanitize(link_text)
107
- href = sanitize(href)
108
- end
109
- content_tag(:a, link_text, link_attributes.merge('href' => href), !!options[:sanitize]) + punctuation.reverse.join('')
110
- end
111
- end
112
- end
113
-
114
- # Turns all email addresses into clickable links. If a block is given,
115
- # each email is yielded and the result is used as the link text.
116
- def auto_link_email_addresses(text, html_options = {}, options = {})
117
- text.gsub(AUTO_EMAIL_RE) do
118
- text = $&
71
+ private
72
+
73
+ AUTO_LINK_RE = %r{
74
+ (?: ([0-9A-Za-z+.:-]+:)// | www\. )
75
+ [^\s<]+
76
+ }x
77
+
78
+ # regexps for determining context, used high-volume
79
+ AUTO_LINK_CRE = [/<[^>]+$/, /^[^>]*>/, /<a\b.*?>/i, /<\/a>/i]
80
+
81
+ AUTO_EMAIL_RE = /[\w.!#\$%+-]+@[\w-]+(?:\.[\w-]+)+/
82
+
83
+ BRACKETS = { ']' => '[', ')' => '(', '}' => '{' }
84
+
85
+ # Turns all urls into clickable links. If a block is given, each url
86
+ # is yielded and the result is used as the link text.
87
+ def auto_link_urls(text, html_options = {}, options = {})
88
+ link_attributes = html_options.stringify_keys
89
+ text.gsub(AUTO_LINK_RE) do
90
+ scheme, href = $1, $&
91
+ punctuation = []
92
+
93
+ if auto_linked?($`, $')
94
+ # do not change string; URL is already linked
95
+ href
96
+ else
97
+ # don't include trailing punctuation character as part of the URL
98
+ while href.sub!(/[^\w\/-]$/, '')
99
+ punctuation.push $&
100
+ if opening = BRACKETS[punctuation.last] and href.scan(opening).size > href.scan(punctuation.last).size
101
+ href << punctuation.pop
102
+ break
103
+ end
104
+ end
105
+
106
+ link_text = block_given?? yield(href) : href
107
+ href = 'http://' + href unless scheme
108
+
109
+ unless options[:sanitize] == false
110
+ link_text = sanitize(link_text)
111
+ href = sanitize(href)
112
+ end
113
+ content_tag(:a, link_text, link_attributes.merge('href' => href), !!options[:sanitize]) + punctuation.reverse.join('')
114
+ end
115
+ end
116
+ end
119
117
 
120
- if auto_linked?($`, $')
121
- text.html_safe
122
- else
123
- display_text = (block_given?) ? yield(text) : text
118
+ # Turns all email addresses into clickable links. If a block is given,
119
+ # each email is yielded and the result is used as the link text.
120
+ def auto_link_email_addresses(text, html_options = {}, options = {})
121
+ text.gsub(AUTO_EMAIL_RE) do
122
+ text = $&
123
+
124
+ if auto_linked?($`, $')
125
+ text.html_safe
126
+ else
127
+ display_text = (block_given?) ? yield(text) : text
128
+
129
+ unless options[:sanitize] == false
130
+ text = sanitize(text)
131
+ display_text = sanitize(display_text) unless text == display_text
132
+ end
133
+ mail_to text, display_text, html_options
134
+ end
135
+ end
136
+ end
124
137
 
125
- unless options[:sanitize] == false
126
- text = sanitize(text)
127
- display_text = sanitize(display_text) unless text == display_text
128
- end
129
- mail_to text, display_text, html_options
138
+ # Detects already linked context or position in the middle of a tag
139
+ def auto_linked?(left, right)
140
+ (left =~ AUTO_LINK_CRE[0] and right =~ AUTO_LINK_CRE[1]) or
141
+ (left.rindex(AUTO_LINK_CRE[2]) and $' !~ AUTO_LINK_CRE[3])
142
+ end
130
143
  end
131
144
  end
132
145
  end
133
-
134
- # Detects already linked context or position in the middle of a tag
135
- def auto_linked?(left, right)
136
- (left =~ AUTO_LINK_CRE[0] and right =~ AUTO_LINK_CRE[1]) or
137
- (left.rindex(AUTO_LINK_CRE[2]) and $' !~ AUTO_LINK_CRE[3])
138
- end
146
+ end
139
147
  end
140
148
  end
141
149
  end
@@ -84,12 +84,17 @@ class TestRailsAutolink < MiniTest::Unit::TestCase
84
84
 
85
85
  def test_auto_link_should_sanitize_input_when_sanitize_option_is_not_false
86
86
  link_raw = %{http://www.rubyonrails.com?id=1&num=2}
87
- assert_equal %{<a href="http://www.rubyonrails.com?id=1&num=2">http://www.rubyonrails.com?id=1&num=2</a>}, auto_link(link_raw)
87
+ malicious_script = '<script>alert("malicious!")</script>'
88
+ assert_equal %{<a href="http://www.rubyonrails.com?id=1&num=2">http://www.rubyonrails.com?id=1&num=2</a>}, auto_link("#{link_raw}#{malicious_script}")
89
+ assert auto_link("#{link_raw}#{malicious_script}").html_safe?
88
90
  end
89
91
 
90
92
  def test_auto_link_should_not_sanitize_input_when_sanitize_option_is_false
91
93
  link_raw = %{http://www.rubyonrails.com?id=1&num=2}
92
- assert_equal %{<a href="http://www.rubyonrails.com?id=1&num=2">http://www.rubyonrails.com?id=1&num=2</a>}, auto_link(link_raw, :sanitize => false)
94
+ malicious_script = '<script>alert("malicious!")</script>'
95
+
96
+ assert_equal %{<a href="http://www.rubyonrails.com?id=1&num=2">http://www.rubyonrails.com?id=1&num=2</a><script>alert("malicious!")</script>}, auto_link("#{link_raw}#{malicious_script}", :sanitize => false)
97
+ assert !auto_link("#{link_raw}#{malicious_script}", :sanitize => false).html_safe?
93
98
  end
94
99
 
95
100
  def test_auto_link_other_protocols
@@ -114,7 +119,7 @@ class TestRailsAutolink < MiniTest::Unit::TestCase
114
119
  linked5 = %('<a href="#close">close</a> <a href="http://www.example.com"><b>www.example.com</b></a>')
115
120
  assert_equal linked1, auto_link(linked1)
116
121
  assert_equal linked2, auto_link(linked2)
117
- assert_equal linked3, auto_link(linked3)
122
+ assert_equal linked3, auto_link(linked3, :sanitize => false)
118
123
  assert_equal linked4, auto_link(linked4)
119
124
  assert_equal linked5, auto_link(linked5)
120
125
 
@@ -130,14 +135,25 @@ class TestRailsAutolink < MiniTest::Unit::TestCase
130
135
  assert_equal %(<p><a href="#{url1}">#{url1}</a><br /><a href="#{url2}">#{url2}</a><br /></p>), auto_link("<p>#{url1}<br />#{url2}<br /></p>")
131
136
  end
132
137
 
133
- def test_auto_link_should_not_be_html_safe
134
- email_raw = 'santiago@wyeworks.com'
135
- link_raw = 'http://www.rubyonrails.org'
136
-
137
- assert !auto_link(nil).html_safe?, 'should not be html safe'
138
- assert !auto_link('').html_safe?, 'should not be html safe'
139
- assert !auto_link("#{link_raw} #{link_raw} #{link_raw}").html_safe?, 'should not be html safe'
140
- assert !auto_link("hello #{email_raw}").html_safe?, 'should not be html safe'
138
+ def test_auto_link_should_be_html_safe
139
+ email_raw = 'santiago@wyeworks.com'
140
+ link_raw = 'http://www.rubyonrails.org'
141
+ malicious_script = '<script>alert("malicious!")</script>'
142
+
143
+ assert auto_link(nil).html_safe?, 'should be html safe'
144
+ assert auto_link('').html_safe?, 'should be html safe'
145
+ assert auto_link("#{link_raw} #{link_raw} #{link_raw}").html_safe?, 'should be html safe'
146
+ assert auto_link("hello #{email_raw}").html_safe?, 'should be html safe'
147
+ assert auto_link("hello #{email_raw} #{malicious_script}").html_safe?, 'should be html safe'
148
+ end
149
+
150
+ def test_auto_link_should_not_be_html_safe_when_sanitize_option_false
151
+ email_raw = 'santiago@wyeworks.com'
152
+ link_raw = 'http://www.rubyonrails.org'
153
+
154
+ assert !auto_link("hello", :sanitize => false).html_safe?, 'should not be html safe'
155
+ assert !auto_link("#{link_raw} #{link_raw} #{link_raw}", :sanitize => false).html_safe?, 'should not be html safe'
156
+ assert !auto_link("hello #{email_raw}", :sanitize => false).html_safe?, 'should not be html safe'
141
157
  end
142
158
 
143
159
  def test_auto_link_email_address
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_autolink
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 0
10
- version: 1.0.0
9
+ - 1
10
+ version: 1.0.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Aaron Patterson
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-02 00:00:00 Z
18
+ date: 2011-05-06 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rails
@@ -25,12 +25,13 @@ dependencies:
25
25
  requirements:
26
26
  - - ~>
27
27
  - !ruby/object:Gem::Version
28
- hash: 3
28
+ hash: 18
29
29
  segments:
30
30
  - 3
31
31
  - 1
32
32
  - 0
33
- version: 3.1.0
33
+ - a
34
+ version: 3.1.0.a
34
35
  type: :runtime
35
36
  version_requirements: *id001
36
37
  - !ruby/object:Gem::Dependency