]> git.wincent.com - wikitext.git/blob - spec/link_sanitizing_spec.rb
6e433dbee7a718ef1e9da19f3184f2ab6396c76d
[wikitext.git] / spec / link_sanitizing_spec.rb
1 #!/usr/bin/env ruby
2 # encoding: utf-8
3 # Copyright 2007-2009 Wincent Colaiuta. All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are met:
7 #
8 # 1. Redistributions of source code must retain the above copyright notice,
9 #    this list of conditions and the following disclaimer.
10 # 2. Redistributions in binary form must reproduce the above copyright notice,
11 #    this list of conditions and the following disclaimer in the documentation
12 #    and/or other materials provided with the distribution.
13
14 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
18 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 # POSSIBILITY OF SUCH DAMAGE.
25
26 require File.join(File.dirname(__FILE__), 'spec_helper.rb')
27 require 'wikitext'
28
29 describe Wikitext, 'sanitizing a link target' do
30   it 'should complain if passed nil' do
31     lambda { Wikitext::Parser.sanitize_link_target(nil) }.should raise_error
32   end
33
34   it 'should complain if passed <' do
35     lambda { Wikitext::Parser.sanitize_link_target('<') }.should raise_error(RangeError, /</)
36   end
37
38   it 'should complain if passed >' do
39     lambda { Wikitext::Parser.sanitize_link_target('>') }.should raise_error(RangeError, />/)
40   end
41
42   it 'should do nothing on zero-length input' do
43     Wikitext::Parser.sanitize_link_target('').should == ''
44   end
45
46   it 'should do nothing to embedded spaces' do
47     Wikitext::Parser.sanitize_link_target('hello world').should == 'hello world'
48   end
49
50   it 'should eat leading spaces' do
51     Wikitext::Parser.sanitize_link_target(' hello world').should == 'hello world'
52     Wikitext::Parser.sanitize_link_target('  hello world').should == 'hello world'
53     Wikitext::Parser.sanitize_link_target('   hello world').should == 'hello world'
54     Wikitext::Parser.sanitize_link_target('    hello world').should == 'hello world'
55     Wikitext::Parser.sanitize_link_target('     hello world').should == 'hello world'
56     Wikitext::Parser.sanitize_link_target('      hello world').should == 'hello world'
57   end
58
59   it 'should eat trailing spaces' do
60     Wikitext::Parser.sanitize_link_target('hello world ').should == 'hello world'
61     Wikitext::Parser.sanitize_link_target('hello world  ').should == 'hello world'
62     Wikitext::Parser.sanitize_link_target('hello world   ').should == 'hello world'
63     Wikitext::Parser.sanitize_link_target('hello world    ').should == 'hello world'
64     Wikitext::Parser.sanitize_link_target('hello world     ').should == 'hello world'   # was a crasher
65     Wikitext::Parser.sanitize_link_target('hello world      ').should == 'hello world'  # was a crasher
66
67     # same but with lots of entities to force a reallocation (we were crashing under reallocation)
68     expected = '&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;'
69     Wikitext::Parser.sanitize_link_target('""""""""""      ').should == expected
70   end
71
72   it 'should eat leading and trailing spaces combined' do
73     Wikitext::Parser.sanitize_link_target(' hello world     ').should == 'hello world'
74     Wikitext::Parser.sanitize_link_target('  hello world    ').should == 'hello world'
75     Wikitext::Parser.sanitize_link_target('   hello world   ').should == 'hello world'
76     Wikitext::Parser.sanitize_link_target('    hello world  ').should == 'hello world'
77     Wikitext::Parser.sanitize_link_target('     hello world  ').should == 'hello world'
78     Wikitext::Parser.sanitize_link_target('      hello world ').should == 'hello world'
79   end
80
81   it 'should return nothing for input consisting entirely of spaces' do
82     Wikitext::Parser.sanitize_link_target(' ').should == ''
83     Wikitext::Parser.sanitize_link_target('  ').should == ''
84     Wikitext::Parser.sanitize_link_target('   ').should == ''
85     Wikitext::Parser.sanitize_link_target('    ').should == ''
86     Wikitext::Parser.sanitize_link_target('     ').should == ''
87     Wikitext::Parser.sanitize_link_target('      ').should == ''
88   end
89
90   it 'should convert double quotes into named entities' do
91     Wikitext::Parser.sanitize_link_target('hello "world"').should == 'hello &quot;world&quot;'
92   end
93
94   it 'should convert ampersands into named entities' do
95     Wikitext::Parser.sanitize_link_target('hello & goodbye').should == 'hello &amp; goodbye'
96   end
97
98   it 'should convert non-ASCII hexadecimal entities' do
99     Wikitext::Parser.sanitize_link_target('cañon').should == 'ca&#x00f1;on'
100   end
101
102   it 'should handle mixed scenarios (ampersands, double-quotes and non-ASCII)' do
103     Wikitext::Parser.sanitize_link_target('foo, "bar" & baz €').should == 'foo, &quot;bar&quot; &amp; baz &#x20ac;'
104   end
105
106   # here we're exercising the _Wikitext_utf8_to_utf32 function
107   describe 'with invalidly encoded input' do
108     it 'should raise an exception for missing second byte' do
109       lambda {
110         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::TWO_BYTES_MISSING_SECOND_BYTE)
111       }.should raise_error(Wikitext::Parser::Error, /truncated/)
112       lambda {
113         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::TWO_BYTES_MISSING_SECOND_BYTE)
114       }.should raise_error(Wikitext::Parser::Error, /truncated/)
115     end
116
117     it 'should raise an exception for malformed second byte' do
118       lambda {
119         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::TWO_BYTES_MALFORMED_SECOND_BYTE)
120       }.should raise_error(Wikitext::Parser::Error, /malformed/)
121       lambda {
122         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::TWO_BYTES_MALFORMED_SECOND_BYTE)
123       }.should raise_error(Wikitext::Parser::Error, /malformed/)
124     end
125
126     it 'should raise an exception for overlong sequence' do
127       lambda {
128         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::OVERLONG)
129       }.should raise_error(Wikitext::Parser::Error, /overlong/)
130       lambda {
131         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::OVERLONG)
132       }.should raise_error(Wikitext::Parser::Error, /overlong/)
133
134       # alternate
135       lambda {
136         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::OVERLONG_ALT)
137       }.should raise_error(Wikitext::Parser::Error, /overlong/)
138       lambda {
139         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::OVERLONG_ALT)
140       }.should raise_error(Wikitext::Parser::Error, /overlong/)
141     end
142
143     it 'should raise an exception for missing second byte in three-byte sequence' do
144       lambda {
145         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::THREE_BYTES_MISSING_SECOND_BYTE)
146       }.should raise_error(Wikitext::Parser::Error, /truncated/)
147       lambda {
148         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::THREE_BYTES_MISSING_SECOND_BYTE)
149       }.should raise_error(Wikitext::Parser::Error, /truncated/)
150     end
151
152     it 'should raise an exception for missing third byte in three-byte sequence' do
153       lambda {
154         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::THREE_BYTES_MISSING_THIRD_BYTE)
155       }.should raise_error(Wikitext::Parser::Error, /truncated/)
156       lambda {
157         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::THREE_BYTES_MISSING_THIRD_BYTE)
158       }.should raise_error(Wikitext::Parser::Error, /truncated/)
159     end
160
161     it 'should raise an exception for malformed second byte in three-byte sequence' do
162       lambda {
163         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::THREE_BYTES_MALFORMED_SECOND_BYTE)
164       }.should raise_error(Wikitext::Parser::Error, /malformed/)
165       lambda {
166         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::THREE_BYTES_MALFORMED_SECOND_BYTE)
167       }.should raise_error(Wikitext::Parser::Error, /malformed/)
168     end
169
170     it 'should raise an exception for malformed third byte in three-byte sequence' do
171       lambda {
172         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::THREE_BYTES_MALFORMED_THIRD_BYTE)
173       }.should raise_error(Wikitext::Parser::Error, /malformed/)
174       lambda {
175         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::THREE_BYTES_MALFORMED_THIRD_BYTE)
176       }.should raise_error(Wikitext::Parser::Error, /malformed/)
177     end
178
179     it 'should raise an exception for missing second byte in four-byte sequence' do
180       lambda {
181         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::FOUR_BYTES_MISSING_SECOND_BYTE)
182       }.should raise_error(Wikitext::Parser::Error, /truncated/)
183       lambda {
184         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::FOUR_BYTES_MISSING_SECOND_BYTE)
185       }.should raise_error(Wikitext::Parser::Error, /truncated/)
186     end
187
188     it 'should raise an exception for missing third byte in four-byte sequence' do
189       lambda {
190         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::FOUR_BYTES_MISSING_THIRD_BYTE)
191       }.should raise_error(Wikitext::Parser::Error, /truncated/)
192       lambda {
193         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::FOUR_BYTES_MISSING_THIRD_BYTE)
194       }.should raise_error(Wikitext::Parser::Error, /truncated/)
195     end
196
197     it 'should raise an exception for missing fourth byte in four-byte sequence' do
198       lambda {
199         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::FOUR_BYTES_MISSING_FOURTH_BYTE)
200       }.should raise_error(Wikitext::Parser::Error, /truncated/)
201       lambda {
202         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::FOUR_BYTES_MISSING_FOURTH_BYTE)
203       }.should raise_error(Wikitext::Parser::Error, /truncated/)
204     end
205
206     it 'should raise an exception for illegal first byte in four-byte sequence' do
207       lambda {
208         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::FOUR_BYTES_ILLEGAL_FIRST_BYTE)
209       }.should raise_error(Wikitext::Parser::Error, /overlong/)
210       lambda {
211         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::FOUR_BYTES_ILLEGAL_FIRST_BYTE)
212       }.should raise_error(Wikitext::Parser::Error, /overlong/)
213
214       lambda {
215         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::FOUR_BYTES_ILLEGAL_FIRST_BYTE_ALT)
216       }.should raise_error(Wikitext::Parser::Error, /overlong/)
217       lambda {
218         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::FOUR_BYTES_ILLEGAL_FIRST_BYTE_ALT)
219       }.should raise_error(Wikitext::Parser::Error, /overlong/)
220
221       lambda {
222         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::FOUR_BYTES_ILLEGAL_FIRST_BYTE_ALT2)
223       }.should raise_error(Wikitext::Parser::Error, /overlong/)
224       lambda {
225         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::FOUR_BYTES_ILLEGAL_FIRST_BYTE_ALT2)
226       }.should raise_error(Wikitext::Parser::Error, /overlong/)
227     end
228
229     it 'should raise an exception for unexpected bytes' do
230       lambda {
231         Wikitext::Parser.sanitize_link_target(UTF8::Invalid::UNEXPECTED_BYTE)
232       }.should raise_error(Wikitext::Parser::Error, /unexpected/)
233       lambda {
234         Wikitext::Parser.sanitize_link_target('good text' + UTF8::Invalid::UNEXPECTED_BYTE)
235       }.should raise_error(Wikitext::Parser::Error, /unexpected/)
236     end
237   end
238 end