KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_wx_data_view_hyperlink_renderer.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <boost/test/unit_test.hpp>
21
22#include <vector>
23#include <wx/string.h>
24
26
27
29
30
31BOOST_AUTO_TEST_SUITE( HyperlinkDvRenderer )
32
33
35{
36 std::vector<RUN> runs;
37 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "plain text" ), runs );
38
39 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
40 BOOST_CHECK_EQUAL( runs[0].text, wxString( "plain text" ) );
41 BOOST_CHECK( runs[0].href.IsEmpty() );
42}
43
44
46{
47 std::vector<RUN> runs;
48 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[label](https://example.com)" ), runs );
49
50 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
51 BOOST_CHECK_EQUAL( runs[0].text, wxString( "label" ) );
52 BOOST_CHECK_EQUAL( runs[0].href, wxString( "https://example.com" ) );
53}
54
55
56BOOST_AUTO_TEST_CASE( TextLinkText )
57{
58 std::vector<RUN> runs;
59 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "before [label](https://example.com) after" ), runs );
60
61 BOOST_REQUIRE_EQUAL( runs.size(), 3u );
62 BOOST_CHECK_EQUAL( runs[0].text, wxString( "before " ) );
63 BOOST_CHECK( runs[0].href.IsEmpty() );
64 BOOST_CHECK_EQUAL( runs[1].text, wxString( "label" ) );
65 BOOST_CHECK_EQUAL( runs[1].href, wxString( "https://example.com" ) );
66 BOOST_CHECK_EQUAL( runs[2].text, wxString( " after" ) );
67 BOOST_CHECK( runs[2].href.IsEmpty() );
68}
69
70
71BOOST_AUTO_TEST_CASE( AdjacentLinks )
72{
73 std::vector<RUN> runs;
74 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[a](https://a.test)[b](https://b.test)" ), runs );
75
76 BOOST_REQUIRE_EQUAL( runs.size(), 2u );
77 BOOST_CHECK_EQUAL( runs[0].text, wxString( "a" ) );
78 BOOST_CHECK_EQUAL( runs[0].href, wxString( "https://a.test" ) );
79 BOOST_CHECK_EQUAL( runs[1].text, wxString( "b" ) );
80 BOOST_CHECK_EQUAL( runs[1].href, wxString( "https://b.test" ) );
81}
82
83
84BOOST_AUTO_TEST_CASE( UnclosedBracket )
85{
86 std::vector<RUN> runs;
87 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "unclosed [bracket" ), runs );
88
89 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
90 BOOST_CHECK_EQUAL( runs[0].text, wxString( "unclosed [bracket" ) );
91 BOOST_CHECK( runs[0].href.IsEmpty() );
92}
93
94
95BOOST_AUTO_TEST_CASE( BracketsNoParens )
96{
97 std::vector<RUN> runs;
98 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[label] no parens" ), runs );
99
100 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
101 BOOST_CHECK_EQUAL( runs[0].text, wxString( "[label] no parens" ) );
102 BOOST_CHECK( runs[0].href.IsEmpty() );
103}
104
105
107{
108 std::vector<RUN> runs;
109 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[](https://example.com)" ), runs );
110
111 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
112 BOOST_CHECK_EQUAL( runs[0].text, wxString( "" ) );
113 BOOST_CHECK_EQUAL( runs[0].href, wxString( "https://example.com" ) );
114}
115
116
117BOOST_AUTO_TEST_CASE( EmptyHrefRejected )
118{
119 std::vector<RUN> runs;
120 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[label]()" ), runs );
121
122 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
123 BOOST_CHECK_EQUAL( runs[0].text, wxString( "label" ) );
124 BOOST_CHECK( runs[0].href.IsEmpty() );
125}
126
127
128BOOST_AUTO_TEST_CASE( BalancedParensInUrl )
129{
130 std::vector<RUN> runs;
131 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[doc](file:///foo (1).pdf)" ), runs );
132
133 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
134 BOOST_CHECK_EQUAL( runs[0].text, wxString( "doc" ) );
135 BOOST_CHECK_EQUAL( runs[0].href, wxString( "file:///foo (1).pdf" ) );
136}
137
138
139BOOST_AUTO_TEST_CASE( ArrayIndexInPlainText )
140{
141 std::vector<RUN> runs;
142 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "array[0] index" ), runs );
143
144 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
145 BOOST_CHECK_EQUAL( runs[0].text, wxString( "array[0] index" ) );
146 BOOST_CHECK( runs[0].href.IsEmpty() );
147}
148
149
151{
152 std::vector<RUN> runs;
153 HYPERLINK_DV_RENDERER::ParseRuns( wxEmptyString, runs );
154
155 BOOST_CHECK( runs.empty() );
156}
157
158
159BOOST_AUTO_TEST_CASE( LinkPlainLink )
160{
161 std::vector<RUN> runs;
162 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[a](https://a.test) middle [b](https://b.test)" ), runs );
163
164 BOOST_REQUIRE_EQUAL( runs.size(), 3u );
165 BOOST_CHECK_EQUAL( runs[0].href, wxString( "https://a.test" ) );
166 BOOST_CHECK_EQUAL( runs[1].text, wxString( " middle " ) );
167 BOOST_CHECK( runs[1].href.IsEmpty() );
168 BOOST_CHECK_EQUAL( runs[2].href, wxString( "https://b.test" ) );
169}
170
171
172BOOST_AUTO_TEST_CASE( NestedBracketInLabel )
173{
174 std::vector<RUN> runs;
175 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[foo [bar]](https://example.com)" ), runs );
176
177 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
178 BOOST_CHECK_EQUAL( runs[0].text, wxString( "[foo [bar]](https://example.com)" ) );
179 BOOST_CHECK( runs[0].href.IsEmpty() );
180}
181
182
183BOOST_AUTO_TEST_CASE( UnsafeUncPathRejected )
184{
185 std::vector<RUN> runs;
186 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[click](\\\\server\\share\\foo.exe)" ), runs );
187
188 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
189 BOOST_CHECK_EQUAL( runs[0].text, wxString( "click" ) );
190 BOOST_CHECK( runs[0].href.IsEmpty() );
191}
192
193
194BOOST_AUTO_TEST_CASE( UnsafeJavascriptRejected )
195{
196 std::vector<RUN> runs;
197 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[click](javascript:alert(1))" ), runs );
198
199 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
200 BOOST_CHECK_EQUAL( runs[0].text, wxString( "click" ) );
201 BOOST_CHECK( runs[0].href.IsEmpty() );
202}
203
204
205BOOST_AUTO_TEST_CASE( UnsafeFileExeRejected )
206{
207 std::vector<RUN> runs;
208 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[click](file:///C:/Windows/System32/cmd.exe)" ), runs );
209
210 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
211 BOOST_CHECK_EQUAL( runs[0].text, wxString( "click" ) );
212 BOOST_CHECK( runs[0].href.IsEmpty() );
213}
214
215
216BOOST_AUTO_TEST_CASE( SafeFilePdfAccepted )
217{
218 std::vector<RUN> runs;
219 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[spec](file:///docs/spec.pdf)" ), runs );
220
221 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
222 BOOST_CHECK_EQUAL( runs[0].text, wxString( "spec" ) );
223 BOOST_CHECK_EQUAL( runs[0].href, wxString( "file:///docs/spec.pdf" ) );
224}
225
226
227BOOST_AUTO_TEST_CASE( SafeUncPathAccepted )
228{
229 std::vector<RUN> runs;
230 HYPERLINK_DV_RENDERER::ParseRuns( wxString( "[spec](\\\\server\\share\\foo.pdf)" ), runs );
231
232 BOOST_REQUIRE_EQUAL( runs.size(), 1u );
233 BOOST_CHECK_EQUAL( runs[0].text, wxString( "spec" ) );
234 BOOST_CHECK_EQUAL( runs[0].href, wxString( "\\\\server\\share\\foo.pdf" ) );
235}
236
237
238BOOST_AUTO_TEST_CASE( IsSafeUrlDirect )
239{
240 BOOST_CHECK( HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "http://example.com" ) ) );
241 BOOST_CHECK( HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "HTTPS://EXAMPLE.COM" ) ) );
242 BOOST_CHECK( HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "file:///home/user/doc.pdf" ) ) );
243
244 BOOST_CHECK( !HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "" ) ) );
245 BOOST_CHECK( !HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "ftp://example.com" ) ) );
246 BOOST_CHECK( !HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "javascript:alert(1)" ) ) );
247 BOOST_CHECK( !HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "data:text/html,<script>" ) ) );
248 BOOST_CHECK( !HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "\\\\server\\share\\foo.exe" ) ) );
249 BOOST_CHECK( !HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "mailto:[email protected]" ) ) );
250 BOOST_CHECK( !HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "file:///foo.exe" ) ) );
251 BOOST_CHECK( !HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "file:///FOO.EXE" ) ) );
252 BOOST_CHECK( !HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "file:///foo.bat" ) ) );
253
254 BOOST_CHECK( HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "\\\\server\\share\\foo.pdf" ) ) );
255 BOOST_CHECK( HYPERLINK_DV_RENDERER::IsSafeUrl( wxString( "\\\\server\\share\\Spec.PDF" ) ) );
256}
257
258
259BOOST_AUTO_TEST_CASE( StripMarkupPlainText )
260{
261 BOOST_CHECK_EQUAL( HYPERLINK_DV_RENDERER::StripMarkup( wxString( "plain text" ) ), wxString( "plain text" ) );
262}
263
264
265BOOST_AUTO_TEST_CASE( StripMarkupSingleLink )
266{
267 BOOST_CHECK_EQUAL( HYPERLINK_DV_RENDERER::StripMarkup( wxString( "See [the spec](https://foo.com/spec) here" ) ),
268 wxString( "See the spec here" ) );
269}
270
271
272BOOST_AUTO_TEST_CASE( StripMarkupDropsUnsafeUrl )
273{
274 BOOST_CHECK_EQUAL( HYPERLINK_DV_RENDERER::StripMarkup( wxString( "Run [this](\\\\evil\\foo.exe) now" ) ),
275 wxString( "Run this now" ) );
276}
277
278
279BOOST_AUTO_TEST_CASE( StripMarkupEmpty )
280{
281 BOOST_CHECK_EQUAL( HYPERLINK_DV_RENDERER::StripMarkup( wxEmptyString ), wxEmptyString );
282}
283
284
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL(result, "25.4")