Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: tools/clang/plugins/tests/ipc.cpp

Issue 1665363002: Clang plugin to check that unstable types are not used in IPC. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix typos Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Blacklisted typedefs
6 typedef __INTMAX_TYPE__ intmax_t;
7 typedef __UINTMAX_TYPE__ uintmax_t;
8 typedef int intptr_t;
9 typedef unsigned int uintptr_t;
10 typedef __WINT_TYPE__ wint_t;
11 typedef __SIZE_TYPE__ size_t;
12 typedef __SIZE_TYPE__ rsize_t;
13 typedef long ssize_t;
14 typedef __PTRDIFF_TYPE__ ptrdiff_t;
15 typedef unsigned int dev_t;
16 typedef int off_t;
17 typedef long clock_t;
18 typedef int time_t;
19 typedef long suseconds_t;
20
21 // Other typedefs
22 typedef int int32_t;
23 typedef unsigned int uint32_t;
24 typedef long int64_t;
25 typedef unsigned long uint64_t;
26
27 namespace std {
28 template <class T>
29 struct allocator {};
30
31 template <class T, class A = allocator<T>>
32 struct vector {};
33
34 template <class F, class S>
35 struct pair {};
36 }
37
38 namespace base {
39 class Pickle {};
40
41 template <class T, class... Ts>
42 struct Tuple {
43 T value;
44 };
45 }
46
47 namespace IPC {
48 template <class... T>
49 struct CheckedTuple {
50 typedef base::Tuple<T...> Tuple;
51 };
52
53 template <class T>
54 struct ParamTraits {
55 static void Write(base::Pickle*, const T&) {}
56 };
57
58 template <class T>
59 void WriteParam(base::Pickle* pickle, const T& value) {
60 ParamTraits<T>::Write(pickle, value);
61 }
62 }
63
64 #if 1
65
66 /* Test IPC::WriteParam() usage in templates. ERRORS: 6 */
67
68 struct Data {
69 uint32_t value;
70 };
71
72 template <>
73 struct IPC::ParamTraits<Data> {
74 static void Write(base::Pickle* pickle, const Data& p) {
75 // OK: WriteParam() called in explicit specialization
76 WriteParam(pickle, p.value); // OK
77 }
78 };
79
80 template <class T>
81 struct Container {
82 T value;
83 };
84
85 template <class T>
86 struct IPC::ParamTraits<Container<T>> {
87 static void Write(base::Pickle* pickle, const Container<T>& container) {
88 // ERROR: T is not explicitly referenced
89 IPC::WriteParam(pickle, container.value); // ERROR
90 WriteParam(pickle, container.value); // ERROR
91
92 // OK: T explicitly referenced
93 IPC::WriteParam<T>(pickle, container.value); // OK
94 WriteParam<T>(pickle, container.value); // OK
95
96 // OK: explicit cast to non-dependent allowed type
97 WriteParam(pickle, static_cast<uint32_t>(container.value)); // OK
98
99 // ERROR: explicit cast to non-dependent banned type
100 WriteParam(pickle, static_cast<long>(container.value)); // ERROR
101 }
102 };
103
104 template <class T, class... Ts>
105 struct MultiContainer {
106 T value;
107 };
108
109 template <class T, class... Ts>
110 struct IPC::ParamTraits<MultiContainer<T, Ts...>> {
111 static void Write(base::Pickle* pickle,
112 const MultiContainer<T, Ts...>& container) {
113 // OK: template argument explicitly referenced
114 bool helper[] = {(WriteParam<Ts>(pickle, container.value), true)...}; // OK
115 (void)helper;
116 }
117 };
118
119 template <class T>
120 struct SomeClass {
121 static void Write(base::Pickle* pickle) {
122 // ERROR: WriteParam() can only be used in ParamTraits templates
123 T p;
124 IPC::WriteParam(pickle, p); // ERROR
125 }
126 };
127
128 template <class T>
129 void SomeWriteFunction(base::Pickle* pickle) {
130 // ERROR: WriteParam() can only be used in ParamTraits templates
131 T p;
132 IPC::WriteParam(pickle, p); // ERROR
133 [&](){
134 IPC::WriteParam(pickle, p); // ERROR
135 }();
136 }
137
138 void TestWriteParamInTemplates() {
139 SomeClass<int>::Write(nullptr);
140 SomeWriteFunction<uint32_t>(nullptr);
141 }
142
143 #endif
144
145 #if 1
146
147 /* Test IPC::CheckedTuple. ERRORS: 5 */
148
149 #define IPC_TUPLE(...) IPC::CheckedTuple<__VA_ARGS__>::Tuple
150
151 #define IPC_MESSAGE_DECL(name, id, in_tuple) \
152 struct name ## Meta_ ## id { \
153 using InTuple = in_tuple; \
154 };
155
156 #define IPC_TEST_MESSAGE(id, in) \
157 IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
158
159 struct Empty {};
160
161 IPC_TEST_MESSAGE(__COUNTER__, (bool, size_t, Empty, long)) // 2 ERRORs
162
163 typedef std::vector<long> long1D;
164 typedef std::vector<long1D> long2D;
165 IPC_TEST_MESSAGE(__COUNTER__, (bool, long2D)) // ERROR
166
167 IPC_TEST_MESSAGE(__COUNTER__, (char, short, std::pair<size_t, bool>)) // ERROR
168
169 IPC_TEST_MESSAGE(__COUNTER__, (std::vector<std::vector<long&>&>&)) // ERROR
170
171 #endif
172
173 #if 1
174
175 /* Check IPC::WriteParam() arguments. ERRORS: 31 */
176
177 // ERRORS: 21
178 void TestWriteParamArgument() {
179 #define CALL_WRITEPARAM(Type) \
180 { \
181 Type p; \
182 IPC::WriteParam(nullptr, p); \
183 }
184
185 // ERROR: blacklisted types / typedefs
186 CALL_WRITEPARAM(long) // ERROR
187 CALL_WRITEPARAM(unsigned long) // ERROR
188 CALL_WRITEPARAM(intmax_t) // ERROR
189 CALL_WRITEPARAM(uintmax_t) // ERROR
190 CALL_WRITEPARAM(intptr_t) // ERROR
191 CALL_WRITEPARAM(uintptr_t) // ERROR
192 CALL_WRITEPARAM(wint_t) // ERROR
193 CALL_WRITEPARAM(size_t) // ERROR
194 CALL_WRITEPARAM(rsize_t) // ERROR
195 CALL_WRITEPARAM(ssize_t) // ERROR
196 CALL_WRITEPARAM(ptrdiff_t) // ERROR
197 CALL_WRITEPARAM(dev_t) // ERROR
198 CALL_WRITEPARAM(off_t) // ERROR
199 CALL_WRITEPARAM(clock_t) // ERROR
200 CALL_WRITEPARAM(time_t) // ERROR
201 CALL_WRITEPARAM(suseconds_t) // ERROR
202
203 // ERROR: typedef to blacklisted typedef
204 typedef size_t my_size;
205 CALL_WRITEPARAM(my_size) // ERROR
206
207 // ERROR: expression ends up with type "unsigned long"
208 {
209 uint64_t p = 0;
210 IPC::WriteParam(nullptr, p + 1); // ERROR
211 }
212
213 // ERROR: long chain of typedefs, ends up with blacklisted typedef
214 {
215 typedef size_t my_size_base;
216 typedef const my_size_base my_size;
217 typedef my_size& my_size_ref;
218 my_size_ref p = 0;
219 IPC::WriteParam(nullptr, p); // ERROR
220 }
221
222 // ERROR: template specialization references blacklisted type
223 CALL_WRITEPARAM(std::vector<long>) // ERROR
224 CALL_WRITEPARAM(std::vector<size_t>) // ERROR
225
226 // OK: typedef to blacklisted type
227 typedef long my_long;
228 CALL_WRITEPARAM(my_long) // OK
229
230 // OK: other types / typedefs
231 CALL_WRITEPARAM(char) // OK
232 CALL_WRITEPARAM(int) // OK
233 CALL_WRITEPARAM(uint32_t) // OK
234 CALL_WRITEPARAM(int64_t) // OK
235
236 // OK: long chain of typedefs, ends up with non-blacklisted typedef
237 {
238 typedef uint32_t my_int_base;
239 typedef const my_int_base my_int;
240 typedef my_int& my_int_ref;
241 my_int_ref p = 0;
242 IPC::WriteParam(nullptr, p); // OK
243 }
244
245 // OK: template specialization references non-blacklisted type
246 CALL_WRITEPARAM(std::vector<char>) // OK
247 CALL_WRITEPARAM(std::vector<my_long>) // OK
248
249 #undef CALL_WRITEPARAM
250 }
251
252 struct Provider {
253 typedef unsigned int flags;
254
255 short get_short() const { return 0; }
256 uint64_t get_uint64() const { return 0; }
257 long get_long() const { return 0; }
258 unsigned int get_uint() const { return 0; }
259 flags get_flags() const { return 0; }
260 size_t get_size() const { return 0; }
261
262 const std::vector<size_t>& get_sizes() const { return sizes_data; }
263 const std::vector<uint64_t>& get_uint64s() const { return uint64s_data; }
264
265 template <class T>
266 T get() const { return T(); }
267
268 short short_data;
269 unsigned int uint_data;
270 flags flags_data;
271 long long_data;
272 size_t size_data;
273 uint64_t uint64_data;
274 std::vector<size_t> sizes_data;
275 std::vector<uint64_t> uint64s_data;
276 };
277
278 // ERRORS: 10
279 void TestWriteParamMemberArgument() {
280 Provider p;
281
282 IPC::WriteParam(nullptr, p.get<short>()); // OK
283 IPC::WriteParam(nullptr, p.get_short()); // OK
284 IPC::WriteParam(nullptr, p.short_data); // OK
285
286 IPC::WriteParam(nullptr, p.get<unsigned int>()); // OK
287 IPC::WriteParam(nullptr, p.get_uint()); // OK
288 IPC::WriteParam(nullptr, p.uint_data); // OK
289
290 IPC::WriteParam(nullptr, p.get<Provider::flags>()); // OK
291 IPC::WriteParam(nullptr, p.get_flags()); // OK
292 IPC::WriteParam(nullptr, p.flags_data); // OK
293
294 IPC::WriteParam(nullptr, p.get<long>()); // ERROR
295 IPC::WriteParam(nullptr, p.get_long()); // ERROR
296 IPC::WriteParam(nullptr, p.long_data); // ERROR
297
298 IPC::WriteParam(nullptr, p.get<size_t>()); // ERROR
299 IPC::WriteParam(nullptr, p.get_size()); // ERROR
300 IPC::WriteParam(nullptr, p.size_data); // ERROR
301
302 // Information about uint64_t gets lost, and plugin sees WriteParam()
303 // call on unsigned long, which is blacklisted.
304 IPC::WriteParam(nullptr, p.get<uint64_t>()); // ERROR
305 IPC::WriteParam(nullptr, p.get_uint64()); // OK
306 IPC::WriteParam(nullptr, p.uint64_data); // OK
307
308 // Same thing here, WriteParam() sees vector<unsigned long>, and denies it.
309 IPC::WriteParam(nullptr, p.get<std::vector<uint64_t>>()); // ERROR
310 IPC::WriteParam(nullptr, p.get_uint64s()); // OK
311 IPC::WriteParam(nullptr, p.uint64s_data); // OK
312
313 // This one is flaky and depends on whether size_t is typedefed to a
314 // blacklisted type (unsigned long).
315 //IPC::WriteParam(nullptr, p.get<std::vector<uint64_t>>());
316 IPC::WriteParam(nullptr, p.get_sizes()); // ERROR
317 IPC::WriteParam(nullptr, p.sizes_data); // ERROR
318 }
319
320 #endif
321
322 /* ERRORS: 42 */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698