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
25
#include <
widgets/wx_data_view_hyperlink_renderer.h
>
26
27
28
using
RUN
=
HYPERLINK_DV_RENDERER::RUN
;
29
30
31
BOOST_AUTO_TEST_SUITE
( HyperlinkDvRenderer )
32
33
34
BOOST_AUTO_TEST_CASE
( PlainText )
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
45
BOOST_AUTO_TEST_CASE
( SingleLink )
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
56
BOOST_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
71
BOOST_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
84
BOOST_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
95
BOOST_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
106
BOOST_AUTO_TEST_CASE
( EmptyLabel )
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
117
BOOST_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
128
BOOST_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
139
BOOST_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
150
BOOST_AUTO_TEST_CASE
( Empty )
151
{
152
std::vector<RUN> runs;
153
HYPERLINK_DV_RENDERER::ParseRuns
( wxEmptyString, runs );
154
155
BOOST_CHECK( runs.empty() );
156
}
157
158
159
BOOST_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
172
BOOST_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
183
BOOST_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
194
BOOST_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
205
BOOST_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
216
BOOST_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
227
BOOST_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
238
BOOST_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
259
BOOST_AUTO_TEST_CASE
( StripMarkupPlainText )
260
{
261
BOOST_CHECK_EQUAL
(
HYPERLINK_DV_RENDERER::StripMarkup
( wxString(
"plain text"
) ), wxString(
"plain text"
) );
262
}
263
264
265
BOOST_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
272
BOOST_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
279
BOOST_AUTO_TEST_CASE
( StripMarkupEmpty )
280
{
281
BOOST_CHECK_EQUAL
(
HYPERLINK_DV_RENDERER::StripMarkup
( wxEmptyString ), wxEmptyString );
282
}
283
284
285
BOOST_AUTO_TEST_SUITE_END
()
BITMAPS::text
@ text
Definition
bitmaps_list.h:614
HYPERLINK_DV_RENDERER::ParseRuns
static void ParseRuns(const wxString &aValue, std::vector< RUN > &aRuns)
Split aValue into plain text and link runs.
Definition
wx_data_view_hyperlink_renderer.cpp:127
HYPERLINK_DV_RENDERER::StripMarkup
static wxString StripMarkup(const wxString &aValue)
Flatten [label](url) markup, keeping just the label.
Definition
wx_data_view_hyperlink_renderer.cpp:113
HYPERLINK_DV_RENDERER::IsSafeUrl
static bool IsSafeUrl(const wxString &aHref)
Accept only schemes that wxLaunchDefaultBrowser cannot turn into program execution.
Definition
wx_data_view_hyperlink_renderer.cpp:84
HYPERLINK_DV_RENDERER::RUN
Definition
wx_data_view_hyperlink_renderer.h:49
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
Definition
test_api_enums.cpp:71
BOOST_AUTO_TEST_SUITE
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL
BOOST_CHECK_EQUAL(result, "25.4")
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(PlainText)
Definition
test_wx_data_view_hyperlink_renderer.cpp:34
RUN
HYPERLINK_DV_RENDERER::RUN RUN
Definition
test_wx_data_view_hyperlink_renderer.cpp:28
wx_data_view_hyperlink_renderer.h
src
qa
tests
common
test_wx_data_view_hyperlink_renderer.cpp
Generated on Fri Jun 26 2026 00:05:43 for KiCad PCB EDA Suite by
1.13.2