1
0
Fork 0

Merging upstream version 4.66.4:

- any optional non-boolean CLI arguments are passed through python's eval,
  allowing arbitrary code execution [CVE-2024-34062] (Closes: #1070372).

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-05 19:20:00 +01:00
parent cc4eb343db
commit 10170fb64c
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
18 changed files with 64 additions and 52 deletions

View file

@ -2,7 +2,7 @@ default_language_version:
python: python3 python: python3
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0 rev: v4.6.0
hooks: hooks:
- id: check-added-large-files - id: check-added-large-files
- id: check-case-conflict - id: check-case-conflict

View file

@ -413,7 +413,7 @@
" \"\"\"Provides a `total_time` format parameter\"\"\"\n", " \"\"\"Provides a `total_time` format parameter\"\"\"\n",
" @property\n", " @property\n",
" def format_dict(self):\n", " def format_dict(self):\n",
" d = super(TqdmExtraFormat, self).format_dict\n", " d = super().format_dict\n",
" total_time = d[\"elapsed\"] * (d[\"total\"] or 0) / max(d[\"n\"], 1)\n", " total_time = d[\"elapsed\"] * (d[\"total\"] or 0) / max(d[\"n\"], 1)\n",
" d.update(total_time=self.format_interval(total_time) + \" in total\")\n", " d.update(total_time=self.format_interval(total_time) + \" in total\")\n",
" return d\n", " return d\n",

View file

@ -766,7 +766,7 @@ Additional ``bar_format`` parameters may also be defined by overriding
"""Provides a `total_time` format parameter""" """Provides a `total_time` format parameter"""
@property @property
def format_dict(self): def format_dict(self):
d = super(TqdmExtraFormat, self).format_dict d = super().format_dict
total_time = d["elapsed"] * (d["total"] or 0) / max(d["n"], 1) total_time = d["elapsed"] * (d["total"] or 0) / max(d["n"], 1)
d.update(total_time=self.format_interval(total_time) + " in total") d.update(total_time=self.format_interval(total_time) + " in total")
return d return d
@ -982,7 +982,7 @@ custom callback take advantage of this, simply use the return value of
class TqdmExt(std_tqdm): class TqdmExt(std_tqdm):
def update(self, n=1): def update(self, n=1):
displayed = super(TqdmExt, self).update(n) displayed = super().update(n)
if displayed: if displayed:
external_callback(**self.format_dict) external_callback(**self.format_dict)
return displayed return displayed

View file

@ -107,7 +107,7 @@ def cpu_timify(t, timer=None):
class UnicodeIO(IOBase): class UnicodeIO(IOBase):
"""Unicode version of StringIO""" """Unicode version of StringIO"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(UnicodeIO, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.encoding = 'U8' # io.StringIO supports unicode, but no encoding self.encoding = 'U8' # io.StringIO supports unicode, but no encoding
self.text = '' self.text = ''
self.cursor = 0 self.cursor = 0
@ -342,7 +342,7 @@ def test_all_defaults():
class WriteTypeChecker(BytesIO): class WriteTypeChecker(BytesIO):
"""File-like to assert the expected type is written""" """File-like to assert the expected type is written"""
def __init__(self, expected_type): def __init__(self, expected_type):
super(WriteTypeChecker, self).__init__() super().__init__()
self.expected_type = expected_type self.expected_type = expected_type
def write(self, s): def write(self, s):
@ -1095,7 +1095,7 @@ def test_custom_format():
"""Provides a `total_time` format parameter""" """Provides a `total_time` format parameter"""
@property @property
def format_dict(self): def format_dict(self):
d = super(TqdmExtraFormat, self).format_dict d = super().format_dict
total_time = d["elapsed"] * (d["total"] or 0) / max(d["n"], 1) total_time = d["elapsed"] * (d["total"] or 0) / max(d["n"], 1)
d.update(total_time=self.format_interval(total_time) + " in total") d.update(total_time=self.format_interval(total_time) + " in total")
return d return d

View file

@ -21,7 +21,7 @@ class tqdm_asyncio(std_tqdm):
Asynchronous-friendly version of tqdm. Asynchronous-friendly version of tqdm.
""" """
def __init__(self, iterable=None, *args, **kwargs): def __init__(self, iterable=None, *args, **kwargs):
super(tqdm_asyncio, self).__init__(iterable, *args, **kwargs) super().__init__(iterable, *args, **kwargs)
self.iterable_awaitable = False self.iterable_awaitable = False
if iterable is not None: if iterable is not None:
if hasattr(iterable, "__anext__"): if hasattr(iterable, "__anext__"):

View file

@ -21,23 +21,34 @@ def cast(val, typ):
return cast(val, t) return cast(val, t)
except TqdmTypeError: except TqdmTypeError:
pass pass
raise TqdmTypeError(val + ' : ' + typ) raise TqdmTypeError(f"{val} : {typ}")
# sys.stderr.write('\ndebug | `val:type`: `' + val + ':' + typ + '`.\n') # sys.stderr.write('\ndebug | `val:type`: `' + val + ':' + typ + '`.\n')
if typ == 'bool': if typ == 'bool':
if (val == 'True') or (val == ''): if (val == 'True') or (val == ''):
return True return True
elif val == 'False': if val == 'False':
return False return False
else: raise TqdmTypeError(val + ' : ' + typ)
raise TqdmTypeError(val + ' : ' + typ) if typ == 'chr':
try: if len(val) == 1:
return eval(typ + '("' + val + '")') return val.encode()
except Exception: if re.match(r"^\\\w+$", val):
if typ == 'chr': return eval(f'"{val}"').encode()
return chr(ord(eval('"' + val + '"'))).encode() raise TqdmTypeError(f"{val} : {typ}")
else: if typ == 'str':
raise TqdmTypeError(val + ' : ' + typ) return val
if typ == 'int':
try:
return int(val)
except ValueError as exc:
raise TqdmTypeError(f"{val} : {typ}") from exc
if typ == 'float':
try:
return float(val)
except ValueError as exc:
raise TqdmTypeError(f"{val} : {typ}") from exc
raise TqdmTypeError(f"{val} : {typ}")
def posix_pipe(fin, fout, delim=b'\\n', buf_size=256, def posix_pipe(fin, fout, delim=b'\\n', buf_size=256,

View file

@ -17,7 +17,7 @@ class DummyTqdmFile(ObjectWrapper):
"""Dummy file-like that will write to tqdm""" """Dummy file-like that will write to tqdm"""
def __init__(self, wrapped): def __init__(self, wrapped):
super(DummyTqdmFile, self).__init__(wrapped) super().__init__(wrapped)
self._buf = [] self._buf = []
def write(self, x, nolock=False): def write(self, x, nolock=False):

View file

@ -27,7 +27,7 @@ class DiscordIO(MonoWorker):
"""Non-blocking file-like IO using a Discord Bot.""" """Non-blocking file-like IO using a Discord Bot."""
def __init__(self, token, channel_id): def __init__(self, token, channel_id):
"""Creates a new message in the given `channel_id`.""" """Creates a new message in the given `channel_id`."""
super(DiscordIO, self).__init__() super().__init__()
config = ClientConfig() config = ClientConfig()
config.token = token config.token = token
client = Client(config) client = Client(config)
@ -91,10 +91,10 @@ class tqdm_discord(tqdm_auto):
kwargs.pop('token', getenv("TQDM_DISCORD_TOKEN")), kwargs.pop('token', getenv("TQDM_DISCORD_TOKEN")),
kwargs.pop('channel_id', getenv("TQDM_DISCORD_CHANNEL_ID"))) kwargs.pop('channel_id', getenv("TQDM_DISCORD_CHANNEL_ID")))
kwargs['mininterval'] = max(1.5, kwargs.get('mininterval', 1.5)) kwargs['mininterval'] = max(1.5, kwargs.get('mininterval', 1.5))
super(tqdm_discord, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def display(self, **kwargs): def display(self, **kwargs):
super(tqdm_discord, self).display(**kwargs) super().display(**kwargs)
fmt = self.format_dict fmt = self.format_dict
if fmt.get('bar_format', None): if fmt.get('bar_format', None):
fmt['bar_format'] = fmt['bar_format'].replace( fmt['bar_format'] = fmt['bar_format'].replace(
@ -104,7 +104,7 @@ class tqdm_discord(tqdm_auto):
self.dio.write(self.format_meter(**fmt)) self.dio.write(self.format_meter(**fmt))
def clear(self, *args, **kwargs): def clear(self, *args, **kwargs):
super(tqdm_discord, self).clear(*args, **kwargs) super().clear(*args, **kwargs)
if not self.disable: if not self.disable:
self.dio.write("") self.dio.write("")

View file

@ -18,7 +18,7 @@ class _TqdmLoggingHandler(logging.StreamHandler):
self, self,
tqdm_class=std_tqdm # type: Type[std_tqdm] tqdm_class=std_tqdm # type: Type[std_tqdm]
): ):
super(_TqdmLoggingHandler, self).__init__() super().__init__()
self.tqdm_class = tqdm_class self.tqdm_class = tqdm_class
def emit(self, record): def emit(self, record):

View file

@ -27,7 +27,7 @@ class SlackIO(MonoWorker):
"""Non-blocking file-like IO using a Slack app.""" """Non-blocking file-like IO using a Slack app."""
def __init__(self, token, channel): def __init__(self, token, channel):
"""Creates a new message in the given `channel`.""" """Creates a new message in the given `channel`."""
super(SlackIO, self).__init__() super().__init__()
self.client = WebClient(token=token) self.client = WebClient(token=token)
self.text = self.__class__.__name__ self.text = self.__class__.__name__
try: try:
@ -88,10 +88,10 @@ class tqdm_slack(tqdm_auto):
kwargs.pop('token', getenv("TQDM_SLACK_TOKEN")), kwargs.pop('token', getenv("TQDM_SLACK_TOKEN")),
kwargs.pop('channel', getenv("TQDM_SLACK_CHANNEL"))) kwargs.pop('channel', getenv("TQDM_SLACK_CHANNEL")))
kwargs['mininterval'] = max(1.5, kwargs.get('mininterval', 1.5)) kwargs['mininterval'] = max(1.5, kwargs.get('mininterval', 1.5))
super(tqdm_slack, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def display(self, **kwargs): def display(self, **kwargs):
super(tqdm_slack, self).display(**kwargs) super().display(**kwargs)
fmt = self.format_dict fmt = self.format_dict
if fmt.get('bar_format', None): if fmt.get('bar_format', None):
fmt['bar_format'] = fmt['bar_format'].replace( fmt['bar_format'] = fmt['bar_format'].replace(
@ -105,7 +105,7 @@ class tqdm_slack(tqdm_auto):
self.sio.write(self.format_meter(**fmt)) self.sio.write(self.format_meter(**fmt))
def clear(self, *args, **kwargs): def clear(self, *args, **kwargs):
super(tqdm_slack, self).clear(*args, **kwargs) super().clear(*args, **kwargs)
if not self.disable: if not self.disable:
self.sio.write("") self.sio.write("")

View file

@ -27,7 +27,7 @@ class TelegramIO(MonoWorker):
def __init__(self, token, chat_id): def __init__(self, token, chat_id):
"""Creates a new message in the given `chat_id`.""" """Creates a new message in the given `chat_id`."""
super(TelegramIO, self).__init__() super().__init__()
self.token = token self.token = token
self.chat_id = chat_id self.chat_id = chat_id
self.session = Session() self.session = Session()
@ -118,10 +118,10 @@ class tqdm_telegram(tqdm_auto):
self.tgio = TelegramIO( self.tgio = TelegramIO(
kwargs.pop('token', getenv('TQDM_TELEGRAM_TOKEN')), kwargs.pop('token', getenv('TQDM_TELEGRAM_TOKEN')),
kwargs.pop('chat_id', getenv('TQDM_TELEGRAM_CHAT_ID'))) kwargs.pop('chat_id', getenv('TQDM_TELEGRAM_CHAT_ID')))
super(tqdm_telegram, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def display(self, **kwargs): def display(self, **kwargs):
super(tqdm_telegram, self).display(**kwargs) super().display(**kwargs)
fmt = self.format_dict fmt = self.format_dict
if fmt.get('bar_format', None): if fmt.get('bar_format', None):
fmt['bar_format'] = fmt['bar_format'].replace( fmt['bar_format'] = fmt['bar_format'].replace(
@ -131,14 +131,14 @@ class tqdm_telegram(tqdm_auto):
self.tgio.write(self.format_meter(**fmt)) self.tgio.write(self.format_meter(**fmt))
def clear(self, *args, **kwargs): def clear(self, *args, **kwargs):
super(tqdm_telegram, self).clear(*args, **kwargs) super().clear(*args, **kwargs)
if not self.disable: if not self.disable:
self.tgio.write("") self.tgio.write("")
def close(self): def close(self):
if self.disable: if self.disable:
return return
super(tqdm_telegram, self).close() super().close()
if not (self.leave or (self.leave is None and self.pos == 0)): if not (self.leave or (self.leave is None and self.pos == 0)):
self.tgio.delete() self.tgio.delete()

View file

@ -20,7 +20,7 @@ class TqdmCallback(Callback):
tqdm_kwargs : optional tqdm_kwargs : optional
Any other arguments used for all bars. Any other arguments used for all bars.
""" """
super(TqdmCallback, self).__init__(start=start, pretask=pretask) super().__init__(start=start, pretask=pretask)
if tqdm_kwargs: if tqdm_kwargs:
tqdm_class = partial(tqdm_class, **tqdm_kwargs) tqdm_class = partial(tqdm_class, **tqdm_kwargs)
self.tqdm_class = tqdm_class self.tqdm_class = tqdm_class

View file

@ -32,7 +32,7 @@ class tqdm_gui(std_tqdm): # pragma: no cover
kwargs = kwargs.copy() kwargs = kwargs.copy()
kwargs['gui'] = True kwargs['gui'] = True
colour = kwargs.pop('colour', 'g') colour = kwargs.pop('colour', 'g')
super(tqdm_gui, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if self.disable: if self.disable:
return return

View file

@ -80,7 +80,7 @@ class TqdmHBox(HBox):
def __repr__(self, pretty=False): def __repr__(self, pretty=False):
pbar = getattr(self, 'pbar', None) pbar = getattr(self, 'pbar', None)
if pbar is None: if pbar is None:
return super(TqdmHBox, self).__repr__() return super().__repr__()
return pbar.format_meter(**self._json_(pretty)) return pbar.format_meter(**self._json_(pretty))
def _repr_pretty_(self, pp, *_, **__): def _repr_pretty_(self, pp, *_, **__):
@ -220,7 +220,7 @@ class tqdm_notebook(std_tqdm):
kwargs['disable'] = bool(kwargs.get('disable', False)) kwargs['disable'] = bool(kwargs.get('disable', False))
colour = kwargs.pop('colour', None) colour = kwargs.pop('colour', None)
display_here = kwargs.pop('display', True) display_here = kwargs.pop('display', True)
super(tqdm_notebook, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if self.disable or not kwargs['gui']: if self.disable or not kwargs['gui']:
self.disp = lambda *_, **__: None self.disp = lambda *_, **__: None
return return
@ -246,7 +246,7 @@ class tqdm_notebook(std_tqdm):
def __iter__(self): def __iter__(self):
try: try:
it = super(tqdm_notebook, self).__iter__() it = super().__iter__()
for obj in it: for obj in it:
# return super(tqdm...) will not catch exception # return super(tqdm...) will not catch exception
yield obj yield obj
@ -259,7 +259,7 @@ class tqdm_notebook(std_tqdm):
def update(self, n=1): def update(self, n=1):
try: try:
return super(tqdm_notebook, self).update(n=n) return super().update(n=n)
# NB: except ... [ as ...] breaks IPython async KeyboardInterrupt # NB: except ... [ as ...] breaks IPython async KeyboardInterrupt
except: # NOQA except: # NOQA
# cannot catch KeyboardInterrupt when using manual tqdm # cannot catch KeyboardInterrupt when using manual tqdm
@ -272,7 +272,7 @@ class tqdm_notebook(std_tqdm):
def close(self): def close(self):
if self.disable: if self.disable:
return return
super(tqdm_notebook, self).close() super().close()
# Try to detect if there was an error or KeyboardInterrupt # Try to detect if there was an error or KeyboardInterrupt
# in manual mode: if n < total, things probably got wrong # in manual mode: if n < total, things probably got wrong
if self.total and self.n < self.total: if self.total and self.n < self.total:
@ -297,14 +297,14 @@ class tqdm_notebook(std_tqdm):
total : int or float, optional. Total to use for the new bar. total : int or float, optional. Total to use for the new bar.
""" """
if self.disable: if self.disable:
return super(tqdm_notebook, self).reset(total=total) return super().reset(total=total)
_, pbar, _ = self.container.children _, pbar, _ = self.container.children
pbar.bar_style = '' pbar.bar_style = ''
if total is not None: if total is not None:
pbar.max = total pbar.max = total
if not self.total and self.ncols is None: # no longer unknown total if not self.total and self.ncols is None: # no longer unknown total
pbar.layout.width = None # reset width pbar.layout.width = None # reset width
return super(tqdm_notebook, self).reset(total=total) return super().reset(total=total)
def tnrange(*args, **kwargs): def tnrange(*args, **kwargs):

View file

@ -90,7 +90,7 @@ class tqdm_rich(std_tqdm): # pragma: no cover
kwargs['disable'] = bool(kwargs.get('disable', False)) kwargs['disable'] = bool(kwargs.get('disable', False))
progress = kwargs.pop('progress', None) progress = kwargs.pop('progress', None)
options = kwargs.pop('options', {}).copy() options = kwargs.pop('options', {}).copy()
super(tqdm_rich, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if self.disable: if self.disable:
return return
@ -116,7 +116,8 @@ class tqdm_rich(std_tqdm): # pragma: no cover
def close(self): def close(self):
if self.disable: if self.disable:
return return
super(tqdm_rich, self).close() self.display() # print 100%, vis #1306
super().close()
self._prog.__exit__(None, None, None) self._prog.__exit__(None, None, None)
def clear(self, *_, **__): def clear(self, *_, **__):
@ -137,7 +138,7 @@ class tqdm_rich(std_tqdm): # pragma: no cover
""" """
if hasattr(self, '_prog'): if hasattr(self, '_prog'):
self._prog.reset(total=total) self._prog.reset(total=total)
super(tqdm_rich, self).reset(total=total) super().reset(total=total)
def trrange(*args, **kwargs): def trrange(*args, **kwargs):

View file

@ -46,7 +46,7 @@ class TqdmWarning(Warning):
if fp_write is not None: if fp_write is not None:
fp_write("\n" + self.__class__.__name__ + ": " + str(msg).rstrip() + '\n') fp_write("\n" + self.__class__.__name__ + ": " + str(msg).rstrip() + '\n')
else: else:
super(TqdmWarning, self).__init__(msg, *a, **k) super().__init__(msg, *a, **k)
class TqdmExperimentalWarning(TqdmWarning, FutureWarning): class TqdmExperimentalWarning(TqdmWarning, FutureWarning):

View file

@ -53,7 +53,7 @@ class tqdm_tk(std_tqdm): # pragma: no cover
grab = kwargs.pop('grab', False) grab = kwargs.pop('grab', False)
tk_parent = kwargs.pop('tk_parent', None) tk_parent = kwargs.pop('tk_parent', None)
self._cancel_callback = kwargs.pop('cancel_callback', None) self._cancel_callback = kwargs.pop('cancel_callback', None)
super(tqdm_tk, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if self.disable: if self.disable:
return return
@ -172,7 +172,7 @@ class tqdm_tk(std_tqdm): # pragma: no cover
self._tk_pbar.configure(maximum=100, mode="indeterminate") self._tk_pbar.configure(maximum=100, mode="indeterminate")
else: else:
self._tk_pbar.configure(maximum=total, mode="determinate") self._tk_pbar.configure(maximum=total, mode="determinate")
super(tqdm_tk, self).reset(total=total) super().reset(total=total)
@staticmethod @staticmethod
def _tk_dispatching_helper(): def _tk_dispatching_helper():

View file

@ -167,7 +167,7 @@ class SimpleTextIOWrapper(ObjectWrapper):
""" """
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
def __init__(self, wrapped, encoding): def __init__(self, wrapped, encoding):
super(SimpleTextIOWrapper, self).__init__(wrapped) super().__init__(wrapped)
self.wrapper_setattr('encoding', encoding) self.wrapper_setattr('encoding', encoding)
def write(self, s): def write(self, s):
@ -211,7 +211,7 @@ class DisableOnWriteError(ObjectWrapper):
return inner return inner
def __init__(self, wrapped, tqdm_instance): def __init__(self, wrapped, tqdm_instance):
super(DisableOnWriteError, self).__init__(wrapped) super().__init__(wrapped)
if hasattr(wrapped, 'write'): if hasattr(wrapped, 'write'):
self.wrapper_setattr( self.wrapper_setattr(
'write', self.disable_on_exception(tqdm_instance, wrapped.write)) 'write', self.disable_on_exception(tqdm_instance, wrapped.write))
@ -229,7 +229,7 @@ class CallbackIOWrapper(ObjectWrapper):
Wrap a given `file`-like object's `read()` or `write()` to report Wrap a given `file`-like object's `read()` or `write()` to report
lengths to the given `callback` lengths to the given `callback`
""" """
super(CallbackIOWrapper, self).__init__(stream) super().__init__(stream)
func = getattr(stream, method) func = getattr(stream, method)
if method == "write": if method == "write":
@wraps(func) @wraps(func)