Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

Merged
merged 5 commits into from
Jan 7, 2019

Conversation

tirkarthi
Copy link
Member

@tirkarthi tirkarthi commented Dec 22, 2018

https://bugs.python.org/issue35560

@@ -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')
Copy link
Member

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -0,0 +1,2 @@
Removed incorrect assert statement that caused segfault in debug builds.
Copy link
Member

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.

Copy link
Member Author

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.

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')
Copy link
Member

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'.

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')
Copy link
Member

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.

@serhiy-storchaka serhiy-storchaka added type-bug An unexpected behavior, bug, or error needs backport to 3.6 labels Dec 22, 2018
@@ -0,0 +1,3 @@
Removed an incorrect assert statement expecting `min_width` >= 0 in
Copy link
Member

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.
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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.

@tirkarthi
Copy link
Member Author

I printed out min_width of the tests and for negative numbers it's increased by one for the sign bit. I have verified that this passes with a debug build locally and 3.7.1 to make sure there is no change in the output.

./python.exe -c "format(123.0, '00')" # min_width -2 , segfaults
./python.exe -c "format(123.34, '00f')" # min_width -7 , segfaults
./python.exe -c "format(123.34, '00e')" # min_width -11 , segfaults
./python.exe -c "format(123.34, '00g')" # min_width -3 , segfaults
./python.exe -c "format(123.34, '00.10f')" # min_width -11 , segfaults
./python.exe -c "format(123.34, '00.10e')" # min_width -15 , segfaults
./python.exe -c "format(123.34, '00.10g')" # min_width -3 , segfaults
./python.exe -c "format(123.34, '01f')" # min_width -6 , segfaults
./python.exe -c "format(-123.0, '00')" # min_width -3 , segfaults
./python.exe -c "format(-123.34, '00f')" # min_width -8, segfaults
./python.exe -c "format(-123.34, '00e')" # min_width -12, segfaults
./python.exe -c "format(-123.34, '00g')" # min_width -4, segfaults
./python.exe -c "format(-123.34, '00.10f')" # min_width -12 , segfaults
./python.exe -c "format(-123.34, '00.10e')" # min_width -16 , segfaults
./python.exe -c "format(-123.34, '00.10g')" # min_width -4 , segfaults
./python.exe -c "format(-123.34, '01f')" # min_width -7 , segfaults

@tirkarthi
Copy link
Member Author

@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);
Copy link
Member

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.

Copy link
Member Author

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 in min_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 that spec->n_min_width and I don't want to mutate the spec->n_min_width .

  • _PyUnicode_InsertThousandsGrouping is used in two places in formatter_unicode.c and does both places need this change ?

Copy link
Member

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.

@bedevere-bot
Copy link

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 I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@@ -9381,6 +9381,7 @@ _PyUnicode_InsertThousandsGrouping(
PyObject *thousands_sep,
Py_UCS4 *maxchar)
{
min_width = Py_MAX(0, min_width);
Copy link
Member

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.
Copy link
Member

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.

Copy link
Member Author

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.

@miss-islington
Copy link
Contributor

Thanks @tirkarthi for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.7.
🐍🍒⛏🤖

@vstinner
Copy link
Member

vstinner commented Jan 7, 2019

vstinner removed the needs backport to 3.6 label a minute ago

Python 3.6 no longer accepts bugfixes: https://devguide.python.org/#status-of-python-branches

@bedevere-bot
Copy link

GH-11458 is a backport of this pull request to the 3.7 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Jan 7, 2019
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]>
@tirkarthi
Copy link
Member Author

Thanks @vstinner and @serhiy-storchaka for the review.

miss-islington added a commit that referenced this pull request Jan 7, 2019
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]>
@charris
Copy link

charris commented Aug 18, 2019

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.

@tirkarthi
Copy link
Member Author

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?

@charris
Copy link

charris commented Aug 18, 2019

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.

@charris
Copy link

charris commented Aug 18, 2019

Note that this can affect all users running pytest with the --durations flag on python3.6-dbg, it isn't NumPy specific.

@tirkarthi
Copy link
Member Author

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.

@vstinner
Copy link
Member

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.

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?

@charris
Copy link

charris commented Aug 19, 2019

Thanks for considering a backport.

The workaround for us at this point is to not use --durations. It is a nice thing to have, but not critical, and two years from now the testing might move on to 3.7 :) Another possibility is for pytest to rewrite the format expression to not cause the error. I don't why it causes a problem, so any help in that regard would be welcome. See pytest-dev/pytest#5763, which also shows the troublesome line of code.

@ned-deily
Copy link
Member

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.

@miss-islington
Copy link
Contributor

Thanks @tirkarthi for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.6.
🐍🍒⛏🤖

@bedevere-bot
Copy link

GH-23231 is a backport of this pull request to the 3.6 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Nov 10, 2020
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]>
gpshead referenced this pull request Nov 10, 2020
) (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)
ned-deily pushed a commit that referenced this pull request Nov 10, 2020
)

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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants