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
crash in datetime.strftime #57883
Comments
This causes a crash in python 3.2.2 and 3.2, but not in 2.7.2 C:\Python32>python
Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> datetime.datetime(1899,12,31).strftime("%y") The crash happens with %y but not with %Y. |
This bug can not be reproduced in Python 3.2.2 on Ubuntu. |
This is happening on Windows x86 against the current tip. The MS C runtime can handle older dates; it's just that we're taking 1900 off the year at some point. (At least, I think that's what's happening). FWIW you only need time.strftime to reproduce the error: import time
time.strftime("%y", (1899, 1, 1, 0, 0, 0, 0, 0, 0)) If no-one gets there first I'll dig into the timemodule strftime wrapper. |
... and that's because the tm struct defines the tm_year field as an offset from 1900. Sorry for the false start. I'll look at the MS runtime stuff instead |
timemodule.c has the following check: #if defined(_MSC_VER) || defined(sun)
if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) {
PyErr_SetString(PyExc_ValueError,
"strftime() requires year in [1; 9999]");
return NULL;
}
#endif |
Yes, but the MS crt strftime *for %y* requires a year >= 1900 (ie |
Is it relevant that 2.7.2 _does_ throw a correct exception? |
Well, the code in 2.x is quite different from that in 3.x. I'll propose a patch to timemodule.c but I'll have to take |
Somewhere in the code is also/still a seperate check concerning strftime: PythonWin 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on win32.
Portions Copyright 1994-2008 Mark Hammond - see 'Help/About PythonWin' for further copyright information.
>>> import datetime
>>> datetime.datetime(-1, 1, 1)
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
ValueError: year is out of range
>>> datetime.datetime(0, 1, 1)
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
ValueError: year is out of range
>>> datetime.datetime(1, 1, 1)
datetime.datetime(1, 1, 1, 0, 0)
>>> datetime.datetime(1, 1, 1).strftime("Y")
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
ValueError: year=1 is before 1000; the datetime strftime() methods require year >= 1000
>>> |
Yes, sorry. I wasn't clear enough. There *are* still checks |
On IDLE this: Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:06:53) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> from datetime import datetime
>>> datetime(1878, 12, 31).strftime('%d %b %y') causes a crash on Windows. I am surprised that this bug still exists as it is not far off two years old now. |
You should report the bug to Microsoft who distributes a buggy C runtime library. |
On 30/09/2013 12:39, STINNER Victor wrote:
Thank you for your suggestion. But, given that this bug has been present for some two years, I would In practice it is pretty well always necessary in building applications Since there is evidently no workaround for this issue in the Python |
In reality (as I'm sure you can guess) it's just that no-one's got to I'll see if I can dig out whatever code I had managed to change. I'm |
On 30/09/2013 13:14, Tim Golden wrote:
Thank you for your comment Tim. To be honest, Python is just so reliable that I was genuinely very It's hardly a priority but I thought it might be worth a comment in case |
Attached is a patch with tests |
+ if (strchr("y", outbuf[1]) && buf.tm_year < 0) hum... why not simply outbuf[1] == 'y' ? It would be more explicit and less surprising. For the unit test, it would be nice to test also asctime(), even if time.asctime() doesn't use asctime() of the C library. And it's better to run tests on all platforms. Only test_y_before_1900() should behave differently on other platforms, but it would be nice to run test_y_before_1900() on platforms supporting "%y" with year < 1900. In my experience, other operating systems have also their own issues. For example, time.strftime() has a specific test to Windows, but also Solaris and AIX. |
On 06/11/2013 15:23, STINNER Victor wrote:
Ummm. I have no idea what I was thinking about there. I think it was
I'm not sure where time.asctime comes into it. The implementation I'm happy to open up the other tests. TJG |
New changeset 1537f14cc690 by Tim Golden in branch '3.3': New changeset 41a4c55db7f2 by Tim Golden in branch 'default': |
I've committed the changes with a variant of the pre-1900 test running on all platforms. I think there's scope for more testing of the boundary conditions of strftime but that would be for another issue. I want to get this one in now as it's a crasher on Windows. |
New changeset c61147d66843 by Tim Golden in branch 'default': New changeset 49db4851c63b by Tim Golden in branch '3.3': New changeset 3ff7602ee543 by Tim Golden in branch 'default': |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: