GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — gh-52551: Fix encoding issues in strftime() by serhiy-storchaka · Pull Request #125193 · python/cpython Conversation
|
|
@vstinner, could you please review this PR? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| newformat, timetuple, NULL); | ||
| Py_DECREF(newformat); | ||
| } | ||
| if (0) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This if (0) is weird. Why not adding a label after _PyUnicodeWriter_Dealloc() and using goto?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This would require changing more code. Renaming label Done to Error (there are many goto Done in not changed code) and adding new Done label. The if (0) idiom is weird, but used in many places.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
| newformat = _PyUnicodeWriter_Finish(&writer); | ||
| } | ||
| if (newformat != NULL) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to exit early: if (newformat == NULL) goto ....
By the way, only the _PyUnicodeWriter_Finish() code path can fail, no?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This would require adding more labels. The flow would look more complicated.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
| * will be ahead of time... | ||
| */ | ||
| while (1) { | ||
| outbuf = (time_char *)PyMem_Realloc(outbuf, bufsize*sizeof(time_char)); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
You may also add an explicit integer overflow check here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| Py_DECREF(unicode); | ||
| } | ||
|
|
||
| j = i; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
You should declare the j variable here, and I suggest to rename it to start.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
| format[fmtlen++] = (char)c; | ||
| } | ||
| if (fmtlen) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This function is quite big. You might move the code handling format in a sub-function (the whole if block).
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This may be inconvenient, because this code changes several outer variables.: outbuf and bufsize.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I addressed all comments. Perhaps it is now more difficult to review. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I just left minor coding style suggestions that you can ignore.
Thanks for the exhaustive added tests, it's very helpful.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| *outbuf = (time_char *)PyMem_Realloc(*outbuf, | ||
| *bufsize*sizeof(time_char)); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
| *outbuf = (time_char *)PyMem_Realloc(*outbuf, | |
| *bufsize*sizeof(time_char)); | |
| *outbuf = (time_char *)PyMem_Realloc(*outbuf, | |
| *bufsize*sizeof(time_char)); |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| static PyObject * | ||
| time_strftime(PyObject *module, PyObject *args) | ||
| strftime1(time_char **outbuf, size_t *bufsize, |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
nitpick: you might rename the function to time_strftime1() to avoid any conflict with a potential strftime1() name from the C library.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Thank you for your review @vstinner. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Thanks @serhiy-storchaka for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12, 3.13. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Sorry, @serhiy-storchaka, I could not cleanly backport this to |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Sorry, @serhiy-storchaka, I could not cleanly backport this to |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
…5193) Fix time.strftime(), the strftime() method and formatting of the datetime classes datetime, date and time. * Characters not encodable in the current locale are now acceptable in the format string. * Surrogate pairs and sequence of surrogatescape-encoded bytes are no longer recombinated. * Embedded null character no longer terminates the format string. This fixes also pythongh-78662 and pythongh-124531. (cherry picked from commit ad3eac1) Co-authored-by: Serhiy Storchaka <[email protected]>
Fix time.strftime(), the strftime() method and formatting of the datetime classes datetime, date and time. * Characters not encodable in the current locale are now acceptable in the format string. * Surrogate pairs and sequence of surrogatescape-encoded bytes are no longer recombinated. * Embedded null character no longer terminates the format string. This fixes also pythongh-78662 and pythongh-124531. (cherry picked from commit ad3eac1)
|
GH-125657 is a backport of this pull request to the 3.13 branch. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
…5657) Fix time.strftime(), the strftime() method and formatting of the datetime classes datetime, date and time. * Characters not encodable in the current locale are now acceptable in the format string. * Surrogate pairs and sequence of surrogatescape-encoded bytes are no longer recombinated. * Embedded null character no longer terminates the format string. This fixes also gh-78662 and gh-124531. (cherry picked from commit ad3eac1)
…5193) (pythonGH-125657) Fix time.strftime(), the strftime() method and formatting of the datetime classes datetime, date and time. * Characters not encodable in the current locale are now acceptable in the format string. * Surrogate pairs and sequence of surrogatescape-encoded bytes are no longer recombinated. * Embedded null character no longer terminates the format string. This fixes also pythongh-78662 and pythongh-124531. (cherry picked from commit 08ccbb9) Co-authored-by: Serhiy Storchaka <[email protected]> (cherry picked from commit ad3eac1)
…5657) (GH-125661) Fix time.strftime(), the strftime() method and formatting of the datetime classes datetime, date and time. * Characters not encodable in the current locale are now acceptable in the format string. * Surrogate pairs and sequence of surrogatescape-encoded bytes are no longer recombinated. * Embedded null character no longer terminates the format string. This fixes also gh-78662 and gh-124531. (cherry picked from commit 08ccbb9) (cherry picked from commit ad3eac1) Co-authored-by: Serhiy Storchaka <[email protected]>
|
Congrats! That's a nice change. Using Unicode instead of bytes for the internal buffer is a good move. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Fix time.strftime(), the strftime() method and formatting of the datetime classes datetime, date and time. * Characters not encodable in the current locale are now acceptable in the format string. * Surrogate pairs and sequence of surrogatescape-encoded bytes are no longer recombinated. * Embedded null character no longer terminates the format string. This fixes also pythongh-78662 and pythongh-124531.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
datetime.strftime strings can be terminated by "\x00" literals
time.strftime() and Unicode characters on Windows
There was an error while loading. Please reload this page.