-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-35560: Remove incorrect assert statement that caused segfault in debug builds #11288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Lib/test/test_float.py
Outdated
@@ -701,6 +701,12 @@ def test_issue5864(self): | |||
self.assertEqual(format(1234.56, '.4'), '1.235e+03') | |||
self.assertEqual(format(12345.6, '.4'), '1.235e+04') | |||
|
|||
def test_issue35560(self): | |||
self.assertEqual(format(123.0, '00'), '123.0') | |||
self.assertEqual(format(float(123), '00'), '123.0') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
float(123)
is the same as 123.0
. This line is not needed.
The following lines do not add anything for testing purpose too. str.format()
and f-strings just use format()
internally.
But it may be worth to add tests for format strings containing explicit format char '00f', '00e', '00g', and containing precision: '00.20', '0020f', etc. Test also with negative number, -123.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Added test cases as suggested.
- Added
min_width = Py_MAX(0, min_width);
as suggested in https://bugs.python.org/msg332359.
@@ -0,0 +1,2 @@ | |||
Removed incorrect assert statement that caused segfault in debug builds. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is too general and unlikely useful. Please specify place/conditions of the segfault.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a note on the function and assert statement. Thanks.
Lib/test/test_float.py
Outdated
self.assertEqual(format(123.34, '00e'), '1.233400e+02') | ||
self.assertEqual(format(123.340, '00g'), '123.34') | ||
self.assertEqual(format(123.340, '00.10f'), '123.3400000000') | ||
self.assertEqual(format(123.340, '0010f'), '123.340000') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bug is not reproducible with non-zero width. Add instead tests for non-zero precision and other format characters: '00.10e', '00.10g'.
Lib/test/test_float.py
Outdated
self.assertEqual(format(123.0, '00'), '123.0') | ||
self.assertEqual(format(123.34, '00f'), '123.340000') | ||
self.assertEqual(format(123.34, '00e'), '1.233400e+02') | ||
self.assertEqual(format(123.340, '00g'), '123.34') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
123.340 is the same as 123.34.
@@ -0,0 +1,3 @@ | |||
Removed an incorrect assert statement expecting `min_width` >= 0 in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
min_width
and _PyUnicode_InsertThousandsGrouping
are implementation details. Describe the issue in terms of Python.
@@ -0,0 +1,3 @@ | |||
Removed an incorrect assert statement expecting `min_width` >= 0 in | |||
`_PyUnicode_InsertThousandsGrouping` that caused segfault in :func:`format` | |||
in debug builds for certain cases. Patch by Karthikeyan Singaravelan. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are certain cases? This is a concrete case: floating point formatting with zero padding and small width.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the below content okay? It will be helpful if you have any in mind so that I can use it since I don't know how to explain it without the internals in the news entry.
Removed an incorrect assert statement that caused segfault in :func:`format`
in debug builds for floating point formatting with zero padding and small width.
Patch by Karthikeyan Singaravelan.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It LGTM, but native speakers can suggest better wording.
I printed out
|
@vstinner Friendly ping if you can review this or if you have a better fix in mind since you wrote the original version I will be happy to close the PR. |
@@ -9381,6 +9381,7 @@ _PyUnicode_InsertThousandsGrouping( | |||
PyObject *thousands_sep, | |||
Py_UCS4 *maxchar) | |||
{ | |||
min_width = Py_MAX(0, min_width); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to fix the caller of this function instead: Python/formatter_unicode.c.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Victor. Few clarifications :
-
By fixing the caller do you mean
min_width
as inmin_width = Py_MAX(0, spec->n_min_width);
and passing it to_PyUnicode_InsertThousandsGrouping
from Python/formatter_unicode.c without modifying spec->n_min_width ? There is an explicit comment thatspec->n_min_width
and I don't want to mutate thespec->n_min_width
. -
_PyUnicode_InsertThousandsGrouping
is used in two places in formatter_unicode.c and does both places need this change ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, I changed my mind and "min_width = Py_MAX(0, min_width);" in _PyUnicode_InsertThousandsGrouping() is just fine.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
@@ -9381,6 +9381,7 @@ _PyUnicode_InsertThousandsGrouping( | |||
PyObject *thousands_sep, | |||
Py_UCS4 *maxchar) | |||
{ | |||
min_width = Py_MAX(0, min_width); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, I changed my mind and "min_width = Py_MAX(0, min_width);" in _PyUnicode_InsertThousandsGrouping() is just fine.
@@ -0,0 +1,3 @@ | |||
Removed an incorrect assert statement that caused segfault in :func:`format` | |||
in debug builds for floating point formatting with zero padding and small width. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should mention that the only the "n" format is impacted by the bug. I propose:
Fix an assertion error in :func:format
in debug build for floating point formatting with "n" format, zero padding and small width. Release build is not impacted. Patch by Karthikeyan Singaravelan.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Victor for the suggestion I have reworded the entry.
Thanks @tirkarthi for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.7. |
Python 3.6 no longer accepts bugfixes: https://devguide.python.org/#status-of-python-branches |
GH-11458 is a backport of this pull request to the 3.7 branch. |
Fix an assertion error in format() in debug build for floating point formatting with "n" format, zero padding and small width. Release build is not impacted. Patch by Karthikeyan Singaravelan. (cherry picked from commit 3f7983a) Co-authored-by: Xtreak <[email protected]>
Thanks @vstinner and @serhiy-storchaka for the review. |
Fix an assertion error in format() in debug build for floating point formatting with "n" format, zero padding and small width. Release build is not impacted. Patch by Karthikeyan Singaravelan. (cherry picked from commit 3f7983a) Co-authored-by: Xtreak <[email protected]>
Can this be backported to 3.6? It is causing problems on travisCI with pytest. Note that 3.6 is the default python3 on Ubuntu bionic. |
I guess this was a problem only with debug builds that has assert statements and as per discussion release builds are not affected. Can you please add a log of travis build that causes this issue in 3.6? |
See https://travis-ci.org/numpy/numpy/jobs/573310511. NumPy is running python3.6-dbg builds on travisCI bionic as one of our CI tests. |
Note that this can affect all users running pytest with the |
Thanks for the details. This fix was made during 3.6.8 RC1 which was the last bugfix for 3.6. It is in security fixes mode so I will defer to core devs if we need to backport this. |
Python 3.6 no longer accept bugfixes anymore: https://devguide.python.org/#status-of-python-branches @ned-deily is the Python 3.6 release manager. Ned: would you be ok to backport this bugfix which cause practical issues on Travis CI? @charris: Even if Python 3.6 is fixed, I'm not sure that Travis CI is going to get the fix yet. It may take a few weeks or a few months until Travis CI will get the fix. Maybe you should modify pytest tests to skip the test on Python 3.6? |
Thanks for considering a backport. The workaround for us at this point is to not use |
As Victor notes, this issue falls outside the criteria for a security-fix branch like 3.6 and, even if made, a backport to 3.6 is unlikely to make a practical difference to your CI testing any time soon. I think it would be better to concentrate on avoiding the problem in your project’s code since that’s something you control. |
Thanks @tirkarthi for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.6. |
GH-23231 is a backport of this pull request to the 3.6 branch. |
Fix an assertion error in format() in debug build for floating point formatting with "n" format, zero padding and small width. Release build is not impacted. Patch by Karthikeyan Singaravelan. (cherry picked from commit 3f7983a) Co-authored-by: Xtreak <[email protected]>
) (GH-10720) Fix str.format(), float.__format__() and complex.__format__() methods for non-ASCII decimal point when using the "n" formatter. Rewrite _PyUnicode_InsertThousandsGrouping(): it now requires a _PyUnicodeWriter object for the buffer and a Python str object for digits. (cherry picked from commit 59423e3) (cherry picked from commit 6f5fa1b)
) Fix an assertion error in format() in debug build for floating point formatting with "n" format, zero padding and small width. Release build is not impacted. Patch by Karthikeyan Singaravelan. (cherry picked from commit 3f7983a) Co-authored-by: Xtreak <[email protected]>
min_width
. This caused segfault in debug builds for some format string in float. Reference for negativemin_width
:cpython/Python/formatter_unicode.c
Line 529 in 59423e3
https://bugs.python.org/issue35560