diff -Nru wmanager-0.3.0/debian/changelog wmanager-0.3.1/debian/changelog --- wmanager-0.3.0/debian/changelog 2021-08-23 07:48:18.000000000 +0000 +++ wmanager-0.3.1/debian/changelog 2022-08-10 10:09:56.000000000 +0000 @@ -1,9 +1,14 @@ -wmanager (0.3.0-2ubuntu1) impish; urgency=medium +wmanager (0.3.1-1) unstable; urgency=medium - * d/p/0001-Fix-out-of-bounds.patch: fix a bug revealed by the glibc 2.34 - upgrade. LP: #1940816 + * Add the year 2021 to my debian/* copyright notice. + * Explicitly declare dh-sequence-single-binary. + * Declare compliance with Policy 4.6.1 with no changes. + * Add the year 2022 to my debian/* copyright notice. + * New upstream release: + - fixes an out-of-bounds memory write in option parsing; + Closes: #1016540 - -- -- Simon Chopin Mon, 23 Aug 2021 09:48:18 +0200 + -- Peter Pentchev Wed, 10 Aug 2022 13:09:56 +0300 wmanager (0.3.0-2) unstable; urgency=medium diff -Nru wmanager-0.3.0/debian/control wmanager-0.3.1/debian/control --- wmanager-0.3.0/debian/control 2021-08-23 07:48:18.000000000 +0000 +++ wmanager-0.3.1/debian/control 2022-08-10 10:09:56.000000000 +0000 @@ -1,11 +1,11 @@ Source: wmanager Section: x11 Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Peter Pentchev -Standards-Version: 4.5.0 +Maintainer: Peter Pentchev +Standards-Version: 4.6.1 Build-Depends: debhelper-compat (= 13), + dh-sequence-single-binary, cnee, libfltk1.3-dev, python3, diff -Nru wmanager-0.3.0/debian/copyright wmanager-0.3.1/debian/copyright --- wmanager-0.3.0/debian/copyright 2020-11-11 09:03:51.000000000 +0000 +++ wmanager-0.3.1/debian/copyright 2022-08-10 10:09:56.000000000 +0000 @@ -11,7 +11,7 @@ License: GPL-2+ Files: debian/* -Copyright: Copyright (C) 2008 - 2011, 2014 - 2020 Peter Pentchev +Copyright: Copyright (C) 2008 - 2011, 2014 - 2022 Peter Pentchev Copyright (C) 1999 - 2005 Tommi Virtanen License: GPL-2+ diff -Nru wmanager-0.3.0/debian/patches/0001-Fix-out-of-bounds-write.patch wmanager-0.3.1/debian/patches/0001-Fix-out-of-bounds-write.patch --- wmanager-0.3.0/debian/patches/0001-Fix-out-of-bounds-write.patch 2021-08-23 07:48:18.000000000 +0000 +++ wmanager-0.3.1/debian/patches/0001-Fix-out-of-bounds-write.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -From 83f7bf114d356ca3e8ce08739c6cc426b6afd97d Mon Sep 17 00:00:00 2001 -From: Simon Chopin -Date: Mon, 23 Aug 2021 14:53:24 +0200 -Forwarded: https://gitlab.com/wmanager/wmanager/-/merge_requests/1 -Subject: [PATCH] Fix out-of-bounds write - -The _CutString was incorrectly written : it correctly wrote the content -of the strings at the beginning of the destination array, but wrote the -NUL char *after* the end of the array. This leads to both an -out-of-bound write, and a read of uninitialized memory (the final -character in the array). - -This patch solves the problem by replacing the entire function with some -much simpler pointer-arithmetic to skip the '-r' prefix, relying on the -std::string assignment operator to do the actual string copy, leaving it -to them to deal with out-of-bounds stuff ;-) - -It is assumed that this bug is the reason for the recent autopkgtest -failing on Ubuntu when run against glibc2.34, probably due to changes in -the state of memory returned by malloc()? (malloc() being the underlying -function behind the new[] operator). ---- - src/WManager.cc | 34 ++-------------------------------- - 1 file changed, 2 insertions(+), 32 deletions(-) - -diff --git a/src/WManager.cc b/src/WManager.cc -index f5500a9..b130028 100644 ---- a/src/WManager.cc -+++ b/src/WManager.cc -@@ -162,8 +162,8 @@ WManager::CheckArguments(int argc, - if(argv[i][0] == '-' && argv[i][1] == 'r') { - - // we must delete only one argument -- *_ConfigurationFilename = ""; -- *_ConfigurationFilename += _CutString(argv[i], "-r"); -+ // Skip the -r prefix. -+ *_ConfigurationFilename = argv[i]+2; - } else { - - // copy argument to new array -@@ -306,33 +306,3 @@ WManager::_TokenizeAndAddToBrowser(char* entry) - } // end if - } // end if - } -- -- --// cut rest from the beginning of str --char* --WManager::_CutString(const char* str, const char* rest) --{ -- int i = 0; -- int n = 0; -- int length = 0; -- int new_length = 0; -- char* new_str = 0; -- -- -- length = strlen(str); -- new_length = length - strlen(rest); -- -- if(new_length < 0) -- return 0; -- -- new_str = new char[new_length+1]; -- -- for(i = strlen(rest), n = 0; -- i < length; -- i++, n++) { -- new_str[n] = str[i]; -- } -- new_str[new_length+1] = 0; -- -- return new_str; --} --- -2.32.0 - diff -Nru wmanager-0.3.0/debian/patches/series wmanager-0.3.1/debian/patches/series --- wmanager-0.3.0/debian/patches/series 2021-08-23 07:48:18.000000000 +0000 +++ wmanager-0.3.1/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -0001-Fix-out-of-bounds-write.patch diff -Nru wmanager-0.3.0/.editorconfig wmanager-0.3.1/.editorconfig --- wmanager-0.3.0/.editorconfig 1970-01-01 00:00:00.000000000 +0000 +++ wmanager-0.3.1/.editorconfig 2022-08-09 13:38:49.000000000 +0000 @@ -0,0 +1,44 @@ +# https://editorconfig.org/ + +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 + +[*.1] +indent_style = tab +tab_size = 8 + +[*.cc] +indent_style = tab +tab_size = 8 + +[*.H] +indent_style = tab +tab_size = 8 + +[.xinitrc] +indent_style = tab +tab_size = 8 + +[tests/setup.cfg] +indent_style = space +indent_size = 4 + +[tests/tox.ini] +indent_style = space +indent_size = 2 + +[tests/wmseq] +indent_style = space +indent_size = 4 + +[tools/wmanager-loop] +indent_style = tab +tab_size = 8 + +[tools/wmanagerrc-update] +indent_style = tab +tab_size = 8 diff -Nru wmanager-0.3.0/HISTORY wmanager-0.3.1/HISTORY --- wmanager-0.3.0/HISTORY 2020-07-15 17:02:22.000000000 +0000 +++ wmanager-0.3.1/HISTORY 2022-08-09 13:38:49.000000000 +0000 @@ -33,3 +33,15 @@ an equals sign ("=") - removed some diagnostic output when the -r option is used - applied some reliability fixes to the wmanager-loop tool + +v0.3.1 2022/08/09 + - fix an out-of-bounds memory write when parsing the -r command-line + option; thanks to Simon Chopin for finding and fixing the problem! + - run the test suite using the Tox tool + - refresh the Python coding style for the test tool: + - reformat the source code using the black tool + - simplify the type annotations syntax + - use subprocess.run() as appropriate + - use subprocess.Popen() as a context manager as appropriate + - add an EditorConfig definitions file + - use tabs in the .xinitrc sample file diff -Nru wmanager-0.3.0/Makefile wmanager-0.3.1/Makefile --- wmanager-0.3.0/Makefile 2020-07-15 17:02:22.000000000 +0000 +++ wmanager-0.3.1/Makefile 2022-08-09 13:38:49.000000000 +0000 @@ -1,7 +1,7 @@ # Makefile for WManager # # Copyright (C) 1999 M. Tessmer -# Copyright (C) 2016, 2020 Peter Pentchev +# Copyright (C) 2016, 2020, 2022 Peter Pentchev # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -98,7 +98,7 @@ UPD1Z = ${UPD1}.gz # project version -VERSION = 0.3.0 +VERSION = 0.3.1 all: ${PROG} ${MAN1Z} ${LOOP1Z} ${UPD1Z} diff -Nru wmanager-0.3.0/src/WManager.cc wmanager-0.3.1/src/WManager.cc --- wmanager-0.3.0/src/WManager.cc 2020-07-15 17:02:22.000000000 +0000 +++ wmanager-0.3.1/src/WManager.cc 2022-08-09 13:38:49.000000000 +0000 @@ -162,8 +162,8 @@ if(argv[i][0] == '-' && argv[i][1] == 'r') { // we must delete only one argument - *_ConfigurationFilename = ""; - *_ConfigurationFilename += _CutString(argv[i], "-r"); + // Skip the -r prefix. + *_ConfigurationFilename = argv[i]+2; } else { // copy argument to new array @@ -306,33 +306,3 @@ } // end if } // end if } - - -// cut rest from the beginning of str -char* -WManager::_CutString(const char* str, const char* rest) -{ - int i = 0; - int n = 0; - int length = 0; - int new_length = 0; - char* new_str = 0; - - - length = strlen(str); - new_length = length - strlen(rest); - - if(new_length < 0) - return 0; - - new_str = new char[new_length+1]; - - for(i = strlen(rest), n = 0; - i < length; - i++, n++) { - new_str[n] = str[i]; - } - new_str[new_length+1] = 0; - - return new_str; -} diff -Nru wmanager-0.3.0/tests/setup.cfg wmanager-0.3.1/tests/setup.cfg --- wmanager-0.3.0/tests/setup.cfg 1970-01-01 00:00:00.000000000 +0000 +++ wmanager-0.3.1/tests/setup.cfg 2022-08-09 13:38:49.000000000 +0000 @@ -0,0 +1,7 @@ +[flake8] +extend-ignore = E203 +max-line-length = 88 + +[mypy] +python_version = 3.7 +strict = True diff -Nru wmanager-0.3.0/tests/tox.ini wmanager-0.3.1/tests/tox.ini --- wmanager-0.3.0/tests/tox.ini 1970-01-01 00:00:00.000000000 +0000 +++ wmanager-0.3.1/tests/tox.ini 2022-08-09 13:38:49.000000000 +0000 @@ -0,0 +1,56 @@ +[tox] +envlist = + black + pep8 + pep8h + mypy + pylint +skipsdist = True + +[defs] +pyfiles = + wmseq + +[testenv:black] +deps = + black >= 22, < 23 +commands = + black --check {[defs]pyfiles} + +[testenv:black-reformat] +deps = + black >= 22, < 23 +commands = + black {[defs]pyfiles} + +[testenv:pep8] +deps = + flake8 +commands = + flake8 {[defs]pyfiles} + +[testenv:pep8h] +deps = + flake8 + hacking >= 4 +commands = + flake8 {[defs]pyfiles} + +[testenv:mypy] +deps = + mypy +commands = + mypy {[defs]pyfiles} + +[testenv:pylint] +deps = + pylint +commands = + pylint {[defs]pyfiles} + +[testenv:functional] +deps = +allowlist_externals = + xvfb-run +commands = + xvfb-run -a -- python3 -u wmseq diff -Nru wmanager-0.3.0/tests/wmseq wmanager-0.3.1/tests/wmseq --- wmanager-0.3.0/tests/wmseq 2020-07-15 17:02:22.000000000 +0000 +++ wmanager-0.3.1/tests/wmseq 2022-08-09 13:38:49.000000000 +0000 @@ -1,6 +1,8 @@ #!/usr/bin/python3 """Test the operation of the wmanager executable.""" +from __future__ import annotations + import contextlib import dataclasses import errno @@ -15,14 +17,13 @@ import time from typing import ( - Callable, + Callable, # noqa: H301 Dict, Iterator, List, Optional, Tuple, Union, - TYPE_CHECKING, ) @@ -101,13 +102,6 @@ return res -if TYPE_CHECKING: - POPEN_TYPE = subprocess.Popen[ # pylint: disable=unsubscriptable-object - bytes - ] -else: - POPEN_TYPE = subprocess.Popen # pylint: disable=invalid-name - LinesHandler = Callable[[str, bool], None] # pylint: disable=invalid-name @@ -115,18 +109,16 @@ class Child: """A child process's attributes.""" - proc: POPEN_TYPE + proc: subprocess.Popen[bytes] fileno: int dec: IncDecoder handler: List[LinesHandler] -def spawn_child( - cmd: List[str], poller: select.epoll, handler: LinesHandler -) -> Child: +def spawn_child(cmd: List[str], poller: select.epoll, handler: LinesHandler) -> Child: """Spawn a child, create a decoder.""" print(f"Spawning a child process: {' '.join(cmd)}") - proc = subprocess.Popen( + proc = subprocess.Popen( # pylint: disable=consider-using-with cmd, shell=False, stdout=subprocess.PIPE, bufsize=0 ) print(f"- spawned child pid {proc.pid}") @@ -147,9 +139,7 @@ by_fno = {child.fileno: name for name, child in children.items()} events = poller.poll() print(f"Events: {events!r}") - return { - name: children[name] for name in (by_fno[evt[0]] for evt in events) - } + return {name: children[name] for name in (by_fno[evt[0]] for evt in events)} def read_available(child: Child, final: bool = False) -> bool: @@ -200,10 +190,7 @@ child.proc.terminate() res = child.proc.wait() if res not in (0, -signal.SIGTERM): - print( - f"The {name} child exited with " - f"an unexpected code {res}" - ) + print(f"The {name} child exited with an unexpected code {res}") read_available(child, final=True) except BaseException as err: # pylint: disable=broad-except @@ -226,25 +213,23 @@ def cnee_write(cmd: str) -> None: """Send a command via the cnee tool.""" print(f"Sending the {cmd!r} command via cnee") - proc = subprocess.Popen( + res = subprocess.run( ["cnee", "--replay", "--file", "stdin"], - shell=False, - stdin=subprocess.PIPE, - stderr=subprocess.DEVNULL, bufsize=0, + capture_output=True, + check=False, encoding="us-ascii", + input=cmd, + shell=False, ) - assert proc.stdin is not None - print(cmd, file=proc.stdin) - proc.stdin.close() - res = proc.wait() - if res != 0: - sys.exit(f"The cnee tool could not handle {cmd!r}: code {res}") + if res.returncode != 0: + sys.exit( + f"The cnee tool could not handle {cmd!r}: " + f"code {res.returncode}, error output: {res.stderr}" + ) -def xev_create_notify( - name: str, lines: List[str], window_data: WindowData -) -> None: +def xev_create_notify(name: str, lines: List[str], window_data: WindowData) -> None: """A window was created... I guess.""" # pylint: disable=too-many-locals,too-many-statements if window_data.window_id is not None: @@ -260,25 +245,23 @@ values = param.split(" ", 1) if values[0] == "window": if window is not None: - sys.exit( - "Duplicate 'window' on the second {name} line: {lines!r}" - ) + sys.exit("Duplicate 'window' on the second {name} line: {lines!r}") window = values[1] if window is None: sys.exit(f"Expected 'window' on the second {name} line: {lines!r}") - proc = subprocess.Popen( + res = subprocess.run( ["env", "LC_ALL=C.UTF-8", "xwininfo", "-id", window, "-shape"], - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, bufsize=0, + check=False, + capture_output=True, encoding="UTF-8", + shell=False, ) - output, _ = proc.communicate() - if proc.wait() != 0: + if res.returncode != 0: print("- xwininfo could not find it, guess it was not important") return + output = res.stdout prefix_first = f"xwininfo: Window id: {window} " props: Dict[str, int] = {} @@ -303,9 +286,7 @@ print(" - we do not care about this one") return "gather_properties" if rkey in props: - sys.exit( - f"Duplicate key {key!r} in the xwininfo output for {window}" - ) + sys.exit(f"Duplicate key {key!r} in the xwininfo output for {window}") props[rkey] = int(value) if len(props) == len(WIN_PROPS): print(" - got them all!") @@ -361,17 +342,12 @@ break handler = handlers[new_handler] - if ( - handler # pylint: disable=comparison-with-callable - != gather_properties - ): + if handler != gather_properties: # pylint: disable=comparison-with-callable print("Apparently not an interesting window at all") return if len(props) != len(WIN_PROPS): - missing = sorted( - key for key in WIN_PROPS if WIN_PROPS[key] not in props - ) + missing = sorted(key for key, value in WIN_PROPS.items() if value not in props) sys.exit( f"Did not find some properties in " f"the xwininfo output for {window!r}: {missing!r}" @@ -424,9 +400,7 @@ """Run a wmanager test with a click at the specified Y offset.""" print(f"Running a wmanager test, click_dy {click_dy}") - window_data = WindowData( - click_dy=click_dy, window_id=None, window_props={} - ) + window_data = WindowData(click_dy=click_dy, window_id=None, window_props={}) children = {} poller = select.epoll() wmoutput: List[str] = [] @@ -436,9 +410,7 @@ children["xev"] = spawn_child( ["xev", "-root"], poller, - lambda line, final: handle_xev_line( - xev_lines, line, final, window_data - ), + lambda line, final: handle_xev_line(xev_lines, line, final, window_data), ) print("sleeping for a little while") time.sleep(1) @@ -497,9 +469,7 @@ @contextlib.contextmanager -def tempdir( - path: Optional[Union[pathlib.Path, str]] = None -) -> Iterator[pathlib.Path]: +def tempdir(path: Optional[Union[pathlib.Path, str]] = None) -> Iterator[pathlib.Path]: """Create a temporary directory and eventually remove it.""" temp = None try: diff -Nru wmanager-0.3.0/.xinitrc wmanager-0.3.1/.xinitrc --- wmanager-0.3.0/.xinitrc 2020-07-15 17:02:22.000000000 +0000 +++ wmanager-0.3.1/.xinitrc 2022-08-09 13:38:49.000000000 +0000 @@ -19,9 +19,9 @@ # # WINDOWMANAGER is the final environment variable if test "$WM"!="-1" ; then - WINDOWMANAGER=$WM ; + WINDOWMANAGER=$WM ; else - exec $failsafe ; + exec $failsafe ; fi