Merge ~cjwatson/launchpad-buildd:py3-check-implicit-pointer-functions-bytes into launchpad-buildd:master
- Git
- lp:~cjwatson/launchpad-buildd
- py3-check-implicit-pointer-functions-bytes
- Merge into master
Proposed by
Colin Watson
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Colin Watson | ||||
Approved revision: | 75194b4adf1725446f32b3a19a443a8e16209f70 | ||||
Merge reported by: | Otto Co-Pilot | ||||
Merged at revision: | not available | ||||
Proposed branch: | ~cjwatson/launchpad-buildd:py3-check-implicit-pointer-functions-bytes | ||||
Merge into: | launchpad-buildd:master | ||||
Diff against target: |
341 lines (+157/-69) 4 files modified
bin/check-implicit-pointer-functions (+6/-1) debian/changelog (+2/-0) lpbuildd/check_implicit_pointer_functions.py (+23/-22) lpbuildd/tests/test_check_implicit_pointer_functions.py (+126/-46) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tom Wardill (community) | Approve | ||
Review via email: mp+391431@code.launchpad.net |
Commit message
Fix check-implicit-
Description of the change
Build logs aren't necessarily UTF-8, so process them as bytes.
To post a comment you must log in.
- 75194b4... by Colin Watson
-
Fix check-implicit-
pointer- functions on Python 3 Build logs aren't necessarily UTF-8, so process them as bytes.
LP: #1897461
Revision history for this message
Tom Wardill (twom) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/bin/check-implicit-pointer-functions b/bin/check-implicit-pointer-functions |
2 | index 7ff5389..c42d8a6 100755 |
3 | --- a/bin/check-implicit-pointer-functions |
4 | +++ b/bin/check-implicit-pointer-functions |
5 | @@ -22,7 +22,12 @@ def main(): |
6 | "--warnonly", default=False, action="store_true", |
7 | help="Exit zero even if problems are found") |
8 | args = parser.parse_args() |
9 | - problems = filter_log(sys.stdin, sys.stdout, in_line=args.inline) |
10 | + stdin = sys.stdin |
11 | + stdout = sys.stdout |
12 | + if sys.version_info[0] >= 3: |
13 | + stdin = stdin.buffer |
14 | + stdout = stdout.buffer |
15 | + problems = filter_log(stdin, stdout, in_line=args.inline) |
16 | if problems and not args.warnonly: |
17 | return 2 |
18 | else: |
19 | diff --git a/debian/changelog b/debian/changelog |
20 | index 547c167..7dad9a1 100644 |
21 | --- a/debian/changelog |
22 | +++ b/debian/changelog |
23 | @@ -2,6 +2,8 @@ launchpad-buildd (193) UNRELEASED; urgency=medium |
24 | |
25 | * Fix handling of bytes arguments passed to BuildManager.runSubProcess. |
26 | * Fix bytes/text handling in RecipeBuilder.buildTree. |
27 | + * Fix check-implicit-pointer-functions on Python 3: build logs aren't |
28 | + necessarily UTF-8, so process them as bytes (LP: #1897461). |
29 | |
30 | -- Colin Watson <cjwatson@ubuntu.com> Thu, 24 Sep 2020 16:45:27 +0100 |
31 | |
32 | diff --git a/lpbuildd/check_implicit_pointer_functions.py b/lpbuildd/check_implicit_pointer_functions.py |
33 | index 9b8b191..7f28338 100755 |
34 | --- a/lpbuildd/check_implicit_pointer_functions.py |
35 | +++ b/lpbuildd/check_implicit_pointer_functions.py |
36 | @@ -35,28 +35,27 @@ |
37 | from __future__ import print_function |
38 | |
39 | import re |
40 | -import sys |
41 | |
42 | implicit_pattern = re.compile( |
43 | - r"([^:]*):(\d+):(\d+:)? warning: implicit declaration " |
44 | - r"of function [`']([^']*)'") |
45 | + br"([^:]*):(\d+):(\d+:)? warning: implicit declaration " |
46 | + br"of function [`']([^']*)'") |
47 | pointer_pattern = re.compile( |
48 | - r"([^:]*):(\d+):(\d+:)? warning: " |
49 | - r"(" |
50 | - r"(assignment" |
51 | - r"|initialization" |
52 | - r"|return" |
53 | - r"|passing arg \d+ of `[^']*'" |
54 | - r"|passing arg \d+ of pointer to function" |
55 | - r") makes pointer from integer without a cast" |
56 | - r"|" |
57 | - r"cast to pointer from integer of different size)") |
58 | + br"([^:]*):(\d+):(\d+:)? warning: " |
59 | + br"(" |
60 | + br"(assignment" |
61 | + br"|initialization" |
62 | + br"|return" |
63 | + br"|passing arg \d+ of `[^']*'" |
64 | + br"|passing arg \d+ of pointer to function" |
65 | + br") makes pointer from integer without a cast" |
66 | + br"|" |
67 | + br"cast to pointer from integer of different size)") |
68 | |
69 | |
70 | def filter_log(in_file, out_file, in_line=False): |
71 | - last_implicit_filename = "" |
72 | + last_implicit_filename = b"" |
73 | last_implicit_linenum = -1 |
74 | - last_implicit_func = "" |
75 | + last_implicit_func = b"" |
76 | |
77 | errlist = [] |
78 | |
79 | @@ -65,7 +64,7 @@ def filter_log(in_file, out_file, in_line=False): |
80 | if in_line: |
81 | out_file.write(line) |
82 | out_file.flush() |
83 | - if line == '': |
84 | + if line == b'': |
85 | break |
86 | m = implicit_pattern.match(line) |
87 | if m: |
88 | @@ -79,16 +78,18 @@ def filter_log(in_file, out_file, in_line=False): |
89 | pointer_linenum = int(m.group(2)) |
90 | if (last_implicit_filename == pointer_filename |
91 | and last_implicit_linenum == pointer_linenum): |
92 | - err = "Function `%s' implicitly converted to pointer at " \ |
93 | - "%s:%d" % (last_implicit_func, last_implicit_filename, |
94 | - last_implicit_linenum) |
95 | + err = ( |
96 | + b"Function `%s' implicitly converted to pointer at " |
97 | + b"%s:%d" % ( |
98 | + last_implicit_func, last_implicit_filename, |
99 | + last_implicit_linenum)) |
100 | errlist.append(err) |
101 | - out_file.write(err + "\n") |
102 | + out_file.write(err + b"\n") |
103 | |
104 | if errlist: |
105 | if in_line: |
106 | - out_file.write("\n".join(errlist) + "\n\n") |
107 | - out_file.write(""" |
108 | + out_file.write(b"\n".join(errlist) + b"\n\n") |
109 | + out_file.write(b""" |
110 | |
111 | Our automated build log filter detected the problem(s) above that will |
112 | likely cause your package to segfault on architectures where the size of |
113 | diff --git a/lpbuildd/tests/test_check_implicit_pointer_functions.py b/lpbuildd/tests/test_check_implicit_pointer_functions.py |
114 | index 582f1f6..8d604ec 100644 |
115 | --- a/lpbuildd/tests/test_check_implicit_pointer_functions.py |
116 | +++ b/lpbuildd/tests/test_check_implicit_pointer_functions.py |
117 | @@ -1,9 +1,12 @@ |
118 | # Copyright 2011-2020 Canonical Ltd. This software is licensed under the |
119 | # GNU Affero General Public License version 3 (see the file LICENSE). |
120 | |
121 | +import io |
122 | +import os.path |
123 | import re |
124 | +import subprocess |
125 | +import sys |
126 | |
127 | -from six import StringIO |
128 | from testtools import TestCase |
129 | from testtools.matchers import MatchesRegex |
130 | |
131 | @@ -20,88 +23,165 @@ class TestPointerCheckRegexes(TestCase): |
132 | # Regex should match compiler errors that don't include the |
133 | # column number. |
134 | line = ( |
135 | - "/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: " |
136 | - "warning: assignment makes pointer from integer without a cast") |
137 | + b"/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: " |
138 | + b"warning: assignment makes pointer from integer without a cast") |
139 | self.assertIsNot(None, pointer_pattern.match(line)) |
140 | |
141 | def test_catches_pointer_from_integer_with_column_number(self): |
142 | # Regex should match compiler errors that do include the |
143 | # column number. |
144 | line = ( |
145 | - "/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94:7: " |
146 | - "warning: assignment makes pointer from integer without a cast") |
147 | + b"/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94:7: " |
148 | + b"warning: assignment makes pointer from integer without a cast") |
149 | self.assertIsNot(None, pointer_pattern.match(line)) |
150 | |
151 | def test_catches_implicit_function_without_column_number(self): |
152 | # Regex should match compiler errors that don't include the |
153 | # column number. |
154 | line = ( |
155 | - "/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: " |
156 | - "warning: implicit declaration of function 'foo'") |
157 | + b"/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: " |
158 | + b"warning: implicit declaration of function 'foo'") |
159 | self.assertIsNot(None, implicit_pattern.match(line)) |
160 | |
161 | def test_catches_implicit_function_with_column_number(self): |
162 | # Regex should match compiler errors that do include the |
163 | # column number. |
164 | line = ( |
165 | - "/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94:7: " |
166 | - "warning: implicit declaration of function 'foo'") |
167 | + b"/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94:7: " |
168 | + b"warning: implicit declaration of function 'foo'") |
169 | self.assertIsNot(None, implicit_pattern.match(line)) |
170 | |
171 | |
172 | class TestFilterLog(TestCase): |
173 | |
174 | def test_out_of_line_no_errors(self): |
175 | - in_file = StringIO("Innocuous build log\nwith no errors\n") |
176 | - out_file = StringIO() |
177 | + in_file = io.BytesIO(b"Innocuous build log\nwith no errors\n") |
178 | + out_file = io.BytesIO() |
179 | self.assertEqual(0, filter_log(in_file, out_file)) |
180 | - self.assertEqual("", out_file.getvalue()) |
181 | + self.assertEqual(b"", out_file.getvalue()) |
182 | |
183 | def test_out_of_line_errors(self): |
184 | - in_file = StringIO( |
185 | - "Build log with errors\n" |
186 | - "/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: " |
187 | - "warning: implicit declaration of function 'foo'\n" |
188 | - "/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: " |
189 | - "warning: assignment makes pointer from integer without a cast\n" |
190 | - "More build log\n") |
191 | - out_file = StringIO() |
192 | + in_file = io.BytesIO( |
193 | + b"Build log with errors\n" |
194 | + b"/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: " |
195 | + b"warning: implicit declaration of function 'foo'\n" |
196 | + b"/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: " |
197 | + b"warning: assignment makes pointer from integer without a cast\n" |
198 | + b"More build log\n") |
199 | + out_file = io.BytesIO() |
200 | self.assertEqual(1, filter_log(in_file, out_file)) |
201 | self.assertEqual( |
202 | - "Function `foo' implicitly converted to pointer at " |
203 | - "/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94\n", |
204 | + b"Function `foo' implicitly converted to pointer at " |
205 | + b"/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94\n", |
206 | out_file.getvalue()) |
207 | |
208 | def test_in_line_no_errors(self): |
209 | - in_file = StringIO("Innocuous build log\nwith no errors\n") |
210 | - out_file = StringIO() |
211 | + in_file = io.BytesIO(b"Innocuous build log\nwith no errors\n") |
212 | + out_file = io.BytesIO() |
213 | self.assertEqual(0, filter_log(in_file, out_file, in_line=True)) |
214 | self.assertEqual( |
215 | - "Innocuous build log\nwith no errors\n", out_file.getvalue()) |
216 | + b"Innocuous build log\nwith no errors\n", out_file.getvalue()) |
217 | |
218 | def test_in_line_errors(self): |
219 | - in_file = StringIO( |
220 | - "Build log with errors\n" |
221 | - "/build/gtk/ubuntumenuproxymodule.c:94: " |
222 | - "warning: implicit declaration of function 'foo'\n" |
223 | - "/build/gtk/ubuntumenuproxymodule.c:94: " |
224 | - "warning: assignment makes pointer from integer without a cast\n" |
225 | - "More build log\n") |
226 | - out_file = StringIO() |
227 | + in_file = io.BytesIO( |
228 | + b"Build log with errors\n" |
229 | + b"/build/gtk/ubuntumenuproxymodule.c:94: " |
230 | + b"warning: implicit declaration of function 'foo'\n" |
231 | + b"/build/gtk/ubuntumenuproxymodule.c:94: " |
232 | + b"warning: assignment makes pointer from integer without a cast\n" |
233 | + b"More build log\n") |
234 | + out_file = io.BytesIO() |
235 | self.assertEqual(1, filter_log(in_file, out_file, in_line=True)) |
236 | self.assertThat(out_file.getvalue(), MatchesRegex( |
237 | - r"^" + |
238 | + br"^" + |
239 | re.escape( |
240 | - "Build log with errors\n" |
241 | - "/build/gtk/ubuntumenuproxymodule.c:94: " |
242 | - "warning: implicit declaration of function 'foo'\n" |
243 | - "/build/gtk/ubuntumenuproxymodule.c:94: " |
244 | - "warning: assignment makes pointer from integer without a " |
245 | - "cast\n" |
246 | - "Function `foo' implicitly converted to pointer at " |
247 | - "/build/gtk/ubuntumenuproxymodule.c:94\n" |
248 | - "More build log\n" |
249 | - "Function `foo' implicitly converted to pointer at " |
250 | - "/build/gtk/ubuntumenuproxymodule.c:94\n\n\n\n") + |
251 | - r"Our automated build log filter.*", |
252 | + b"Build log with errors\n" |
253 | + b"/build/gtk/ubuntumenuproxymodule.c:94: " |
254 | + b"warning: implicit declaration of function 'foo'\n" |
255 | + b"/build/gtk/ubuntumenuproxymodule.c:94: " |
256 | + b"warning: assignment makes pointer from integer without a " |
257 | + b"cast\n" |
258 | + b"Function `foo' implicitly converted to pointer at " |
259 | + b"/build/gtk/ubuntumenuproxymodule.c:94\n" |
260 | + b"More build log\n" |
261 | + b"Function `foo' implicitly converted to pointer at " |
262 | + b"/build/gtk/ubuntumenuproxymodule.c:94\n\n\n\n") + |
263 | + br"Our automated build log filter.*", |
264 | + flags=re.M | re.S)) |
265 | + |
266 | + |
267 | +class TestCheckImplicitPointerFunctionsScript(TestCase): |
268 | + |
269 | + def setUp(self): |
270 | + super(TestCheckImplicitPointerFunctionsScript, self).setUp() |
271 | + top = os.path.dirname( |
272 | + os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
273 | + self.script = os.path.join( |
274 | + top, "bin", "check-implicit-pointer-functions") |
275 | + |
276 | + def test_out_of_line_no_errors(self): |
277 | + in_bytes = b"Innocuous build log\nwith no errors\n\x80\x81\x82\n" |
278 | + process = subprocess.Popen( |
279 | + [sys.executable, self.script], |
280 | + stdin=subprocess.PIPE, stdout=subprocess.PIPE) |
281 | + out_bytes, _ = process.communicate(in_bytes) |
282 | + self.assertEqual(0, process.poll()) |
283 | + self.assertEqual(b"", out_bytes) |
284 | + |
285 | + def test_out_of_line_errors(self): |
286 | + in_bytes = ( |
287 | + b"Build log with errors\n" |
288 | + b"/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: " |
289 | + b"warning: implicit declaration of function 'foo'\n" |
290 | + b"/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94: " |
291 | + b"warning: assignment makes pointer from integer without a cast\n" |
292 | + b"\x80\x81\x82\n") |
293 | + process = subprocess.Popen( |
294 | + [sys.executable, self.script], |
295 | + stdin=subprocess.PIPE, stdout=subprocess.PIPE) |
296 | + out_bytes, _ = process.communicate(in_bytes) |
297 | + self.assertEqual(2, process.poll()) |
298 | + self.assertEqual( |
299 | + b"Function `foo' implicitly converted to pointer at " |
300 | + b"/build/buildd/gtk+3.0-3.0.0/./gtk/ubuntumenuproxymodule.c:94\n", |
301 | + out_bytes) |
302 | + |
303 | + def test_in_line_no_errors(self): |
304 | + in_bytes = (b"Innocuous build log\nwith no errors\n\x80\x81\x82\n") |
305 | + process = subprocess.Popen( |
306 | + [sys.executable, self.script, "--inline"], |
307 | + stdin=subprocess.PIPE, stdout=subprocess.PIPE) |
308 | + out_bytes, _ = process.communicate(in_bytes) |
309 | + self.assertEqual(0, process.poll()) |
310 | + self.assertEqual( |
311 | + b"Innocuous build log\nwith no errors\n\x80\x81\x82\n", out_bytes) |
312 | + |
313 | + def test_in_line_errors(self): |
314 | + in_bytes = ( |
315 | + b"Build log with errors\n" |
316 | + b"/build/gtk/ubuntumenuproxymodule.c:94: " |
317 | + b"warning: implicit declaration of function 'foo'\n" |
318 | + b"/build/gtk/ubuntumenuproxymodule.c:94: " |
319 | + b"warning: assignment makes pointer from integer without a cast\n" |
320 | + b"\x80\x81\x82\n") |
321 | + process = subprocess.Popen( |
322 | + [sys.executable, self.script, "--inline"], |
323 | + stdin=subprocess.PIPE, stdout=subprocess.PIPE) |
324 | + out_bytes, _ = process.communicate(in_bytes) |
325 | + self.assertEqual(2, process.poll()) |
326 | + self.assertThat(out_bytes, MatchesRegex( |
327 | + br"^" + |
328 | + re.escape( |
329 | + b"Build log with errors\n" |
330 | + b"/build/gtk/ubuntumenuproxymodule.c:94: " |
331 | + b"warning: implicit declaration of function 'foo'\n" |
332 | + b"/build/gtk/ubuntumenuproxymodule.c:94: " |
333 | + b"warning: assignment makes pointer from integer without a " |
334 | + b"cast\n" |
335 | + b"Function `foo' implicitly converted to pointer at " |
336 | + b"/build/gtk/ubuntumenuproxymodule.c:94\n" |
337 | + b"\x80\x81\x82\n" |
338 | + b"Function `foo' implicitly converted to pointer at " |
339 | + b"/build/gtk/ubuntumenuproxymodule.c:94\n\n\n\n") + |
340 | + br"Our automated build log filter.*", |
341 | flags=re.M | re.S)) |