--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: Michael Banck <mba...@debian.org>
Please unblock package pydantic
pydantic (1.7.4-1) unstable; urgency=medium
* Team upload.
* New upstream point release.
- Fixes CVE-2021-29510: Date and datetime parsing could cause an infinite
loop by passing either 'infinity' or float('inf') (Closes: #988480)
* Update watch file to version 4 with current uscan(1) recommended regex.
-- Stefano Rivera <stefa...@debian.org> Fri, 21 May 2021 16:05:17 -0400
[ Reason ]
New upstream point release, with (only) a security fix (DoS).
[ Impact ]
Without this patch, pydantic can be DoSed with "infinity" as a
timestamp.
[ Tests ]
Upstream unit test suite runs during the package build.
There are unit tests for the changes in this release.
[ Risks ]
Upstream maintains support branches, and provided this point release. So
we're not relying on any untested patches.
[ Checklist ]
[x] all changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in testing
unblock pydantic/1.7.4-1
diff -Nru pydantic-1.7.3/debian/changelog pydantic-1.7.4/debian/changelog
--- pydantic-1.7.3/debian/changelog 2021-01-08 03:31:43.000000000 -0400
+++ pydantic-1.7.4/debian/changelog 2021-05-21 16:05:17.000000000 -0400
@@ -1,3 +1,13 @@
+pydantic (1.7.4-1) unstable; urgency=medium
+
+ * Team upload.
+ * New upstream point release.
+ - Fixes CVE-2021-29510: Date and datetime parsing could cause an infinite
+ loop by passing either 'infinity' or float('inf') (Closes: #988480)
+ * Update watch file to version 4 with current uscan(1) recommended regex.
+
+ -- Stefano Rivera <stefa...@debian.org> Fri, 21 May 2021 16:05:17 -0400
+
pydantic (1.7.3-1) unstable; urgency=medium
[ Sandro Tosi ]
diff -Nru pydantic-1.7.3/debian/watch pydantic-1.7.4/debian/watch
--- pydantic-1.7.3/debian/watch 2021-01-08 03:31:43.000000000 -0400
+++ pydantic-1.7.4/debian/watch 2021-05-21 16:05:17.000000000 -0400
@@ -1,2 +1,4 @@
-version=3
-https://github.com/samuelcolvin/pydantic/releases .*/archive/v([\d.]+)\.tar\.gz
+version=4
+opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%@PACKAGE@-$1.tar.gz%" \
+ https://github.com/samuelcolvin/pydantic/releases \
+ (?:.*?/)?v?(\d[\d.]*)\.tar\.gz
diff -Nru pydantic-1.7.3/.github/workflows/ci.yml
pydantic-1.7.4/.github/workflows/ci.yml
--- pydantic-1.7.3/.github/workflows/ci.yml 2020-11-30 19:33:24.000000000
-0400
+++ pydantic-1.7.4/.github/workflows/ci.yml 2021-05-11 15:04:58.000000000
-0400
@@ -80,20 +80,20 @@
COMPILED: yes
DEPS: yes
- - name: uninstall deps
- run: pip uninstall -y cython email-validator typing-extensions devtools
python-dotenv
-
- - name: test compiled without deps
- run: make test
-
- - run: coverage xml
- - uses: codecov/codecov-action@v1.0.14
- with:
- file: ./coverage.xml
- env_vars: COMPILED,DEPS,PYTHON,OS
- env:
- COMPILED: yes
- DEPS: no
+# - name: uninstall deps
+# run: pip uninstall -y cython email-validator typing-extensions devtools
python-dotenv
+#
+# - name: test compiled without deps
+# run: make test
+#
+# - run: coverage xml
+# - uses: codecov/codecov-action@v1.0.14
+# with:
+# file: ./coverage.xml
+# env_vars: COMPILED,DEPS,PYTHON,OS
+# env:
+# COMPILED: yes
+# DEPS: no
- name: remove compiled binaries
run: |
@@ -159,11 +159,12 @@
with:
python-version: '3.7'
- - name: install
- run: make install-testing
-
- - name: test
- run: make test-fastapi
+ - run: echo "skip fastapi for now"
+# - name: install
+# run: make install-testing
+#
+# - name: test
+# run: make test-fastapi
benchmark:
name: run benchmarks
diff -Nru pydantic-1.7.3/HISTORY.md pydantic-1.7.4/HISTORY.md
--- pydantic-1.7.3/HISTORY.md 2020-11-30 19:33:24.000000000 -0400
+++ pydantic-1.7.4/HISTORY.md 2021-05-11 15:04:58.000000000 -0400
@@ -1,3 +1,9 @@
+## v1.7.4 (2021-05-11)
+
+* **Security fix:** Fix `date` and `datetime` parsing so passing either
`'infinity'` or `float('inf')`
+ (or their negative values) does not cause an infinite loop,
+ See security advisory
[CVE-2021-29510](https://github.com/samuelcolvin/pydantic/security/advisories/GHSA-5jqp-qgf6-3pvh)
+
## v1.7.3 (2020-11-30)
Thank you to pydantic's sponsors:
diff -Nru pydantic-1.7.3/pydantic/datetime_parse.py
pydantic-1.7.4/pydantic/datetime_parse.py
--- pydantic-1.7.3/pydantic/datetime_parse.py 2020-11-30 19:33:24.000000000
-0400
+++ pydantic-1.7.4/pydantic/datetime_parse.py 2021-05-11 15:04:58.000000000
-0400
@@ -58,6 +58,8 @@
# if greater than this, the number is in ms, if less than or equal it's in
seconds
# (in seconds this is 11th October 2603, in ms it's 20th August 1970)
MS_WATERSHED = int(2e10)
+# slightly more than datetime.max in ns - (datetime.max -
EPOCH).total_seconds() * 1e9
+MAX_NUMBER = int(3e20)
StrBytesIntFloat = Union[str, bytes, int, float]
@@ -73,6 +75,11 @@
def from_unix_seconds(seconds: Union[int, float]) -> datetime:
+ if seconds > MAX_NUMBER:
+ return datetime.max
+ elif seconds < -MAX_NUMBER:
+ return datetime.min
+
while abs(seconds) > MS_WATERSHED:
seconds /= 1000
dt = EPOCH + timedelta(seconds=seconds)
diff -Nru pydantic-1.7.3/pydantic/version.py pydantic-1.7.4/pydantic/version.py
--- pydantic-1.7.3/pydantic/version.py 2020-11-30 19:33:24.000000000 -0400
+++ pydantic-1.7.4/pydantic/version.py 2021-05-11 15:04:58.000000000 -0400
@@ -1,6 +1,6 @@
__all__ = 'VERSION', 'version_info'
-VERSION = '1.7.3'
+VERSION = '1.7.4'
def version_info() -> str:
diff -Nru pydantic-1.7.3/tests/test_datetime_parse.py
pydantic-1.7.4/tests/test_datetime_parse.py
--- pydantic-1.7.3/tests/test_datetime_parse.py 2020-11-30 19:33:24.000000000
-0400
+++ pydantic-1.7.4/tests/test_datetime_parse.py 2021-05-11 15:04:58.000000000
-0400
@@ -42,11 +42,20 @@
(1_549_316_052_104, date(2019, 2, 4)), # nowish in ms
(1_549_316_052_104_324, date(2019, 2, 4)), # nowish in μs
(1_549_316_052_104_324_096, date(2019, 2, 4)), # nowish in ns
+ ('infinity', date(9999, 12, 31)),
+ ('inf', date(9999, 12, 31)),
+ (float('inf'), date(9999, 12, 31)),
+ ('infinity ', date(9999, 12, 31)),
+ (int('1' + '0' * 100), date(9999, 12, 31)),
+ (1e1000, date(9999, 12, 31)),
+ ('-infinity', date(1, 1, 1)),
+ ('-inf', date(1, 1, 1)),
+ ('nan', ValueError),
],
)
def test_date_parsing(value, result):
- if result == errors.DateError:
- with pytest.raises(errors.DateError):
+ if type(result) == type and issubclass(result, Exception):
+ with pytest.raises(result):
parse_date(value)
else:
assert parse_date(value) == result
@@ -123,11 +132,19 @@
(1_549_316_052_104, datetime(2019, 2, 4, 21, 34, 12, 104_000,
tzinfo=timezone.utc)), # nowish in ms
(1_549_316_052_104_324, datetime(2019, 2, 4, 21, 34, 12, 104_324,
tzinfo=timezone.utc)), # nowish in μs
(1_549_316_052_104_324_096, datetime(2019, 2, 4, 21, 34, 12, 104_324,
tzinfo=timezone.utc)), # nowish in ns
+ ('infinity', datetime(9999, 12, 31, 23, 59, 59, 999999)),
+ ('inf', datetime(9999, 12, 31, 23, 59, 59, 999999)),
+ ('inf ', datetime(9999, 12, 31, 23, 59, 59, 999999)),
+ (1e50, datetime(9999, 12, 31, 23, 59, 59, 999999)),
+ (float('inf'), datetime(9999, 12, 31, 23, 59, 59, 999999)),
+ ('-infinity', datetime(1, 1, 1, 0, 0)),
+ ('-inf', datetime(1, 1, 1, 0, 0)),
+ ('nan', ValueError),
],
)
def test_datetime_parsing(value, result):
- if result == errors.DateTimeError:
- with pytest.raises(errors.DateTimeError):
+ if type(result) == type and issubclass(result, Exception):
+ with pytest.raises(result):
parse_datetime(value)
else:
assert parse_datetime(value) == result
@@ -251,3 +268,24 @@
'type': 'value_error.unicodedecode',
'msg': "'utf-8' codec can't decode byte 0x81 in position 0: invalid
start byte",
}
+
+
+def test_nan():
+ class Model(BaseModel):
+ dt: datetime
+ d: date
+
+ with pytest.raises(ValidationError) as exc_info:
+ Model(dt='nan', d='nan')
+ assert exc_info.value.errors() == [
+ {
+ 'loc': ('dt',),
+ 'msg': 'cannot convert float NaN to integer',
+ 'type': 'value_error',
+ },
+ {
+ 'loc': ('d',),
+ 'msg': 'cannot convert float NaN to integer',
+ 'type': 'value_error',
+ },
+ ]
--- End Message ---