-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
<iomanip>
: std::put_time
should copy unknown conversion specifiers instead of crash
#4820
Comments
See WG14-N3220 7.29.3.5/2:
IIUC
The standard wording for
Ditto, there's nothing wrong with I believe it's UCRT's Personal thought on workaround: Don't call |
@frederick-vs-ja Thanks a lot for the input. Yes my example got a bit wrong while I was trying to do a minimal version of it. I've edited my post to correct it.
Unfortunately this would not solve all the cases. For example From past experiences I think requesting any kind of behavioral changes to the UCRT usually gets ignored. Perhaps the best approach here would be for the |
Fortunately, MSVC STL is not so that huge. I think this is the only concentrated relavent entry to UCRT. Line 749 in ef1d621
AFAIK Perhaps it's still doable to add a |
Ah, as a workaround you meant the STL codebase. I thought you implied the application code on which I'm working on. Yep, I think this is doable and not too complicated. Also it should not affect binary compatibility. @StephanTLavavej Any thoughts on this one? |
@frederick-vs-ja I think you missed this paragraph, WG14-N3220 7.29.3.5/6:
I think that the second part of your analysis is correct - while C says that unrecognized conversion specifiers are UB, C++ says that unrecognized conversion specifiers are copied unchanged ([locale.time.put.members]/1 "Each character that is not part of a format sequence is written to It seems that no UCRT changes are necessary here - instead we should alter the STL's wrapper layer to recognize unknown conversion specifiers and ensure that they're copied unchanged (after 5 seconds of thought, escaping them with |
<iomanip>
: std::put_time
should copy unknown conversion specifiers instead of crash
@StephanTLavavej Will that also cover the cases where some more broken string is passed? For example, lets say I just forward user input to the P.S. I think a much better solution would be for the UCRT team to alter the UB of |
Can you provide a specific example of a "broken string" that does not involve an unknown conversion specifier? |
Hey, for example "%Y-%-m-%-d" but I guess that will also be taken care of by the escaping? Anyway, whichever workaround you choose, still the checks which |
Yeah, Getting UCRT changes is extremely difficult - I think we should pursue STL changes here. |
In that case I would recommend to not use strftime at all and create a complete STL rewrite. I guess you should have access to UCRT source code, so coping most stuff from there would make this task much easier. P.S. This will also solve the issues with std::format crashes when used with Chrono types. |
@StephanTLavavej I've submitted a PR with simple fix: #4840 However, by looking at the code there I see significant effort to avoid So is there any interest in doing STL native version of |
Improved performance and resistance to UCRT/STL specification divergence would be worthwhile, but that has to be balanced against the complexity and maintenance burden of such a change. Our immediate reactions were "rarrrrrgh!" (@barcharcraz) and "uhhhhhhhh?" (@StephanTLavavej) 😹. We wouldn't want to encourage anyone to work on that, but we won't reject the idea out of hand. |
Well, the |
Describe the bug
I know that behind the scenes
std::put_time
does usestrftime
which leads to crash if some kind of invalid input is provided. I haven't exactly read the standard, but the cplusplus.com docs on the function says if anything wrong happens, it should set thefailbit
on the stream and not crash the program. While undefined behavior is allowed forstrftime
on invalid input, this does not seems to be the case forstd::put_time
and this is why I'm reporting this as a bug.Now, some ideas from my research on the topic. According to MS docs the only way to recover from
strftime
error case is to use_set_invalid_parameter_handler
/_set_thread_local_invalid_parameter_handler
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/set-invalid-parameter-handler-set-thread-local-invalid-parameter-handler?view=msvc-170The first one seems unfeasible as it will modify the global CRT invalid handler for C functions. The second option about thread local storage might be a better option if set and unset before/after calling
std::put_time
and using it to properly flag the stream error. This would still trigger an assert in debug mode, but at least it will not crash release versions.But in general, the best solution for me would be for the UCRT team to modify the existing
strftime
implementations or create a completely new variant which can handle errors in a more graceful manner, but if this is not possible at least the STL team should try to handle this case somehow by perhaps using the workaround I've proposed.Command-line test case
Expected behavior
That would be for the program to NOT crash and output "Date time formatting failed due to invalid input".
(Edited: See analysis below.)
STL version
VS 2022 17.6.16
The text was updated successfully, but these errors were encountered: