Merge ~cjwatson/launchpad-buildd:py3-check-implicit-pointer-functions-bytes into launchpad-buildd: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)
Reviewer Review Type Date Requested Status
Tom Wardill (community) Approve
Review via email: mp+391431@code.launchpad.net

Commit message

Fix check-implicit-pointer-functions on Python 3

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
1diff --git a/bin/check-implicit-pointer-functions b/bin/check-implicit-pointer-functions
2index 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:
19diff --git a/debian/changelog b/debian/changelog
20index 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
32diff --git a/lpbuildd/check_implicit_pointer_functions.py b/lpbuildd/check_implicit_pointer_functions.py
33index 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
113diff --git a/lpbuildd/tests/test_check_implicit_pointer_functions.py b/lpbuildd/tests/test_check_implicit_pointer_functions.py
114index 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))

Subscribers

People subscribed via source and target branches