Compare commits
1 Commits
Author | SHA256 | Date | |
---|---|---|---|
94a95f0a1b |
24
CVE-2023-26112.patch
Normal file
24
CVE-2023-26112.patch
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
From a82ea8fb0338f2bd46cf627c4b763094448e6bd7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: cdcadman <mythirty@gmail.com>
|
||||||
|
Date: Wed, 17 May 2023 03:57:08 -0700
|
||||||
|
Subject: [PATCH] Address CVE-2023-26112 ReDoS
|
||||||
|
|
||||||
|
---
|
||||||
|
src/configobj/validate.py | 2 +-
|
||||||
|
src/tests/test_validate_errors.py | 10 +++++++++-
|
||||||
|
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/validate.py b/validate.py
|
||||||
|
index 9267a3f..98d879f 100644
|
||||||
|
--- a/src/configobj/validate.py
|
||||||
|
+++ b/src/configobj/validate.py
|
||||||
|
@@ -541,7 +541,7 @@ class Validator(object):
|
||||||
|
"""
|
||||||
|
|
||||||
|
# this regex does the initial parsing of the checks
|
||||||
|
- _func_re = re.compile(r'(.+?)\((.*)\)', re.DOTALL)
|
||||||
|
+ _func_re = re.compile(r'([^\(\)]+?)\((.*)\)', re.DOTALL)
|
||||||
|
|
||||||
|
# this regex takes apart keyword arguments
|
||||||
|
_key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$', re.DOTALL)
|
||||||
|
|
BIN
configobj-5.0.8.tar.gz
(Stored with Git LFS)
Normal file
BIN
configobj-5.0.8.tar.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
configobj-5.0.9-gh.tar.gz
(Stored with Git LFS)
BIN
configobj-5.0.9-gh.tar.gz
(Stored with Git LFS)
Binary file not shown.
@@ -1,32 +1,3 @@
|
|||||||
-------------------------------------------------------------------
|
|
||||||
Tue Feb 4 08:55:17 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
|
|
||||||
|
|
||||||
- Update to 5.0.9
|
|
||||||
* Drop support for Python 2 and <3.7
|
|
||||||
* Fix CVE-2023-26112, ReDoS attack
|
|
||||||
- Drop CVE-2023-26112.patch, merged upstream
|
|
||||||
- Drop remove_six.patch, fixed upstream
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
Wed Sep 11 12:08:59 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
|
|
||||||
|
|
||||||
- Refresh CVE-2023-26112.patch according to the last state of
|
|
||||||
gh#DiffSK/configobj!236.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
Wed Jan 3 16:47:32 UTC 2024 - Ben Greiner <code@bnavigator.de>
|
|
||||||
|
|
||||||
- Remove six from the rpm requirements. Why would we have
|
|
||||||
remove_six.patch in the first place if we still require it?
|
|
||||||
- Enable unit tests
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
Wed Jan 3 09:46:30 UTC 2024 - Dirk Müller <dmueller@suse.com>
|
|
||||||
|
|
||||||
- require setuptools
|
|
||||||
- remove python2 logic, this makes no sense after
|
|
||||||
"remove_six.patch"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Wed Jul 5 07:29:38 UTC 2023 - Matej Cepl <mcepl@suse.com>
|
Wed Jul 5 07:29:38 UTC 2023 - Matej Cepl <mcepl@suse.com>
|
||||||
|
|
||||||
@@ -60,7 +31,7 @@ Thu Apr 13 22:40:36 UTC 2023 - Matej Cepl <mcepl@suse.com>
|
|||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Mon Jan 16 21:16:58 UTC 2023 - Dirk Müller <dmueller@suse.com>
|
Mon Jan 16 21:16:58 UTC 2023 - Dirk Müller <dmueller@suse.com>
|
||||||
|
|
||||||
- require setuptools
|
- require setuptools
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Tue Dec 4 12:46:48 UTC 2018 - Matej Cepl <mcepl@suse.com>
|
Tue Dec 4 12:46:48 UTC 2018 - Matej Cepl <mcepl@suse.com>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package python-configobj
|
# spec file for package python-configobj
|
||||||
#
|
#
|
||||||
# Copyright (c) 2025 SUSE LLC
|
# Copyright (c) 2023 SUSE LLC
|
||||||
#
|
#
|
||||||
# All modifications and additions to the file contributed by third parties
|
# All modifications and additions to the file contributed by third parties
|
||||||
# remain the property of their copyright owners, unless otherwise agreed
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
@@ -16,25 +16,32 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
%define oldpython python
|
||||||
%{?sle15_python_module_pythons}
|
%{?sle15_python_module_pythons}
|
||||||
Name: python-configobj
|
Name: python-configobj
|
||||||
Version: 5.0.9
|
Version: 5.0.8
|
||||||
Release: 0
|
Release: 0
|
||||||
Summary: Config file reading, writing and validation
|
Summary: Config file reading, writing and validation
|
||||||
License: BSD-3-Clause
|
License: BSD-3-Clause
|
||||||
Group: Development/Languages/Python
|
Group: Development/Languages/Python
|
||||||
URL: https://github.com/DiffSK/configobj
|
URL: https://github.com/DiffSK/configobj
|
||||||
# No tests in PyPI sdist
|
Source: https://files.pythonhosted.org/packages/source/c/configobj/configobj-%{version}.tar.gz
|
||||||
Source: https://github.com/DiffSK/configobj/archive/refs/tags/v%{version}.tar.gz#/configobj-%{version}-gh.tar.gz
|
# PATCH-FIX-UPSTREAM https://github.com/DiffSK/configobj/pull/236 Address CVE-2023-26112 ReDoS
|
||||||
|
Patch0: CVE-2023-26112.patch
|
||||||
|
# PATCH-FIX-UPSTREAM remove_six.patch gh#DiffSK/configobj#239 mcepl@suse.com
|
||||||
|
# We don't need six anymore
|
||||||
|
Patch1: remove_six.patch
|
||||||
BuildRequires: %{python_module pip}
|
BuildRequires: %{python_module pip}
|
||||||
BuildRequires: %{python_module setuptools}
|
|
||||||
BuildRequires: %{python_module wheel}
|
BuildRequires: %{python_module wheel}
|
||||||
BuildRequires: fdupes
|
BuildRequires: fdupes
|
||||||
BuildRequires: python-rpm-macros
|
BuildRequires: python-rpm-macros
|
||||||
|
Requires: python-six
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
# SECTION test
|
# There are no real docs!
|
||||||
BuildRequires: %{python_module pytest}
|
%ifpython2
|
||||||
# /SECTION
|
Obsoletes: %{oldpython}-configobj-docs < %{version}
|
||||||
|
Provides: %{oldpython}-configobj-docs = %{version}
|
||||||
|
%endif
|
||||||
%python_subpackages
|
%python_subpackages
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@@ -66,12 +73,9 @@ It has lots of other features though:
|
|||||||
%pyproject_install
|
%pyproject_install
|
||||||
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
||||||
|
|
||||||
%check
|
|
||||||
%pytest
|
|
||||||
|
|
||||||
%files %{python_files}
|
%files %{python_files}
|
||||||
%{python_sitelib}/configobj
|
%{python_sitelib}/configobj
|
||||||
%{python_sitelib}/validate
|
%{python_sitelib}/validate
|
||||||
%{python_sitelib}/configobj-%{version}.dist-info
|
%{python_sitelib}/configobj-%{version}*-info
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
213
remove_six.patch
Normal file
213
remove_six.patch
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
---
|
||||||
|
setup.py | 1
|
||||||
|
src/configobj.egg-info/requires.txt | 1
|
||||||
|
src/configobj/__init__.py | 49 ++++++++++++++++--------------------
|
||||||
|
3 files changed, 22 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
|
--- a/setup.py
|
||||||
|
+++ b/setup.py
|
||||||
|
@@ -41,7 +41,6 @@ DESCRIPTION = 'Config file reading, writ
|
||||||
|
URL = 'https://github.com/DiffSK/configobj'
|
||||||
|
|
||||||
|
REQUIRES = """
|
||||||
|
- six
|
||||||
|
"""
|
||||||
|
|
||||||
|
VERSION = ''
|
||||||
|
--- a/src/configobj.egg-info/requires.txt
|
||||||
|
+++ b/src/configobj.egg-info/requires.txt
|
||||||
|
@@ -1 +0,0 @@
|
||||||
|
-six
|
||||||
|
--- a/src/configobj/__init__.py
|
||||||
|
+++ b/src/configobj/__init__.py
|
||||||
|
@@ -19,7 +19,6 @@ import sys
|
||||||
|
|
||||||
|
from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
|
||||||
|
|
||||||
|
-import six
|
||||||
|
from ._version import __version__
|
||||||
|
|
||||||
|
# imported lazily to avoid startup performance hit if it isn't used
|
||||||
|
@@ -553,11 +552,11 @@ class Section(dict):
|
||||||
|
"""Fetch the item and do string interpolation."""
|
||||||
|
val = dict.__getitem__(self, key)
|
||||||
|
if self.main.interpolation:
|
||||||
|
- if isinstance(val, six.string_types):
|
||||||
|
+ if isinstance(val, str):
|
||||||
|
return self._interpolate(key, val)
|
||||||
|
if isinstance(val, list):
|
||||||
|
def _check(entry):
|
||||||
|
- if isinstance(entry, six.string_types):
|
||||||
|
+ if isinstance(entry, str):
|
||||||
|
return self._interpolate(key, entry)
|
||||||
|
return entry
|
||||||
|
new = [_check(entry) for entry in val]
|
||||||
|
@@ -580,7 +579,7 @@ class Section(dict):
|
||||||
|
``unrepr`` must be set when setting a value to a dictionary, without
|
||||||
|
creating a new sub-section.
|
||||||
|
"""
|
||||||
|
- if not isinstance(key, six.string_types):
|
||||||
|
+ if not isinstance(key, str):
|
||||||
|
raise ValueError('The key "%s" is not a string.' % key)
|
||||||
|
|
||||||
|
# add the comment
|
||||||
|
@@ -614,11 +613,11 @@ class Section(dict):
|
||||||
|
if key not in self:
|
||||||
|
self.scalars.append(key)
|
||||||
|
if not self.main.stringify:
|
||||||
|
- if isinstance(value, six.string_types):
|
||||||
|
+ if isinstance(value, str):
|
||||||
|
pass
|
||||||
|
elif isinstance(value, (list, tuple)):
|
||||||
|
for entry in value:
|
||||||
|
- if not isinstance(entry, six.string_types):
|
||||||
|
+ if not isinstance(entry, str):
|
||||||
|
raise TypeError('Value is not a string "%s".' % entry)
|
||||||
|
else:
|
||||||
|
raise TypeError('Value is not a string "%s".' % value)
|
||||||
|
@@ -959,7 +958,7 @@ class Section(dict):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
- if not isinstance(val, six.string_types):
|
||||||
|
+ if not isinstance(val, str):
|
||||||
|
# TODO: Why do we raise a KeyError here?
|
||||||
|
raise KeyError()
|
||||||
|
else:
|
||||||
|
@@ -1230,7 +1229,7 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
|
||||||
|
def _load(self, infile, configspec):
|
||||||
|
- if isinstance(infile, six.string_types):
|
||||||
|
+ if isinstance(infile, str):
|
||||||
|
self.filename = infile
|
||||||
|
if os.path.isfile(infile):
|
||||||
|
with open(infile, 'rb') as h:
|
||||||
|
@@ -1298,7 +1297,7 @@ class ConfigObj(Section):
|
||||||
|
break
|
||||||
|
break
|
||||||
|
|
||||||
|
- assert all(isinstance(line, six.string_types) for line in content), repr(content)
|
||||||
|
+ assert all(isinstance(line, str) for line in content), repr(content)
|
||||||
|
content = [line.rstrip('\r\n') for line in content]
|
||||||
|
|
||||||
|
self._parse(content)
|
||||||
|
@@ -1403,7 +1402,7 @@ class ConfigObj(Section):
|
||||||
|
else:
|
||||||
|
line = infile
|
||||||
|
|
||||||
|
- if isinstance(line, six.text_type):
|
||||||
|
+ if isinstance(line, str):
|
||||||
|
# it's already decoded and there's no need to do anything
|
||||||
|
# else, just use the _decode utility method to handle
|
||||||
|
# listifying appropriately
|
||||||
|
@@ -1448,7 +1447,7 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
# No encoding specified - so we need to check for UTF8/UTF16
|
||||||
|
for BOM, (encoding, final_encoding) in list(BOMS.items()):
|
||||||
|
- if not isinstance(line, six.binary_type) or not line.startswith(BOM):
|
||||||
|
+ if not isinstance(line, bytes) or not line.startswith(BOM):
|
||||||
|
# didn't specify a BOM, or it's not a bytestring
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
@@ -1464,9 +1463,9 @@ class ConfigObj(Section):
|
||||||
|
else:
|
||||||
|
infile = newline
|
||||||
|
# UTF-8
|
||||||
|
- if isinstance(infile, six.text_type):
|
||||||
|
+ if isinstance(infile, str):
|
||||||
|
return infile.splitlines(True)
|
||||||
|
- elif isinstance(infile, six.binary_type):
|
||||||
|
+ elif isinstance(infile, bytes):
|
||||||
|
return infile.decode('utf-8').splitlines(True)
|
||||||
|
else:
|
||||||
|
return self._decode(infile, 'utf-8')
|
||||||
|
@@ -1474,12 +1473,8 @@ class ConfigObj(Section):
|
||||||
|
return self._decode(infile, encoding)
|
||||||
|
|
||||||
|
|
||||||
|
- if six.PY2 and isinstance(line, str):
|
||||||
|
- # don't actually do any decoding, since we're on python 2 and
|
||||||
|
- # returning a bytestring is fine
|
||||||
|
- return self._decode(infile, None)
|
||||||
|
# No BOM discovered and no encoding specified, default to UTF-8
|
||||||
|
- if isinstance(infile, six.binary_type):
|
||||||
|
+ if isinstance(infile, bytes):
|
||||||
|
return infile.decode('utf-8').splitlines(True)
|
||||||
|
else:
|
||||||
|
return self._decode(infile, 'utf-8')
|
||||||
|
@@ -1487,7 +1482,7 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
def _a_to_u(self, aString):
|
||||||
|
"""Decode ASCII strings to unicode if a self.encoding is specified."""
|
||||||
|
- if isinstance(aString, six.binary_type) and self.encoding:
|
||||||
|
+ if isinstance(aString, bytes) and self.encoding:
|
||||||
|
return aString.decode(self.encoding)
|
||||||
|
else:
|
||||||
|
return aString
|
||||||
|
@@ -1499,9 +1494,9 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
if is a string, it also needs converting to a list.
|
||||||
|
"""
|
||||||
|
- if isinstance(infile, six.string_types):
|
||||||
|
+ if isinstance(infile, str):
|
||||||
|
return infile.splitlines(True)
|
||||||
|
- if isinstance(infile, six.binary_type):
|
||||||
|
+ if isinstance(infile, bytes):
|
||||||
|
# NOTE: Could raise a ``UnicodeDecodeError``
|
||||||
|
if encoding:
|
||||||
|
return infile.decode(encoding).splitlines(True)
|
||||||
|
@@ -1510,7 +1505,7 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
if encoding:
|
||||||
|
for i, line in enumerate(infile):
|
||||||
|
- if isinstance(line, six.binary_type):
|
||||||
|
+ if isinstance(line, bytes):
|
||||||
|
# NOTE: The isinstance test here handles mixed lists of unicode/string
|
||||||
|
# NOTE: But the decode will break on any non-string values
|
||||||
|
# NOTE: Or could raise a ``UnicodeDecodeError``
|
||||||
|
@@ -1520,7 +1515,7 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
def _decode_element(self, line):
|
||||||
|
"""Decode element to unicode if necessary."""
|
||||||
|
- if isinstance(line, six.binary_type) and self.default_encoding:
|
||||||
|
+ if isinstance(line, bytes) and self.default_encoding:
|
||||||
|
return line.decode(self.default_encoding)
|
||||||
|
else:
|
||||||
|
return line
|
||||||
|
@@ -1532,7 +1527,7 @@ class ConfigObj(Section):
|
||||||
|
Used by ``stringify`` within validate, to turn non-string values
|
||||||
|
into strings.
|
||||||
|
"""
|
||||||
|
- if not isinstance(value, six.string_types):
|
||||||
|
+ if not isinstance(value, str):
|
||||||
|
# intentially 'str' because it's just whatever the "normal"
|
||||||
|
# string type is for the python version we're dealing with
|
||||||
|
return str(value)
|
||||||
|
@@ -1786,7 +1781,7 @@ class ConfigObj(Section):
|
||||||
|
return self._quote(value[0], multiline=False) + ','
|
||||||
|
return ', '.join([self._quote(val, multiline=False)
|
||||||
|
for val in value])
|
||||||
|
- if not isinstance(value, six.string_types):
|
||||||
|
+ if not isinstance(value, str):
|
||||||
|
if self.stringify:
|
||||||
|
# intentially 'str' because it's just whatever the "normal"
|
||||||
|
# string type is for the python version we're dealing with
|
||||||
|
@@ -2111,7 +2106,7 @@ class ConfigObj(Section):
|
||||||
|
if not output.endswith(newline):
|
||||||
|
output += newline
|
||||||
|
|
||||||
|
- if isinstance(output, six.binary_type):
|
||||||
|
+ if isinstance(output, bytes):
|
||||||
|
output_bytes = output
|
||||||
|
else:
|
||||||
|
output_bytes = output.encode(self.encoding or
|
||||||
|
@@ -2353,7 +2348,7 @@ class ConfigObj(Section):
|
||||||
|
This method raises a ``ReloadError`` if the ConfigObj doesn't have
|
||||||
|
a filename attribute pointing to a file.
|
||||||
|
"""
|
||||||
|
- if not isinstance(self.filename, six.string_types):
|
||||||
|
+ if not isinstance(self.filename, str):
|
||||||
|
raise ReloadError()
|
||||||
|
|
||||||
|
filename = self.filename
|
Reference in New Issue
Block a user