rails_autolink 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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