diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2023-07-18 10:36:37 +0100 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2023-07-19 11:03:32 +0100 |
commit | 52bfec7ea0eb0f1a4c5bfa55b0d6b9b6c8808e26 (patch) | |
tree | beb18e234e2a10315513dfb78974b60a3a250731 | |
parent | f07136af570b145fe0df6b142defc9558998bf53 (diff) | |
download | gcc-52bfec7ea0eb0f1a4c5bfa55b0d6b9b6c8808e26.zip gcc-52bfec7ea0eb0f1a4c5bfa55b0d6b9b6c8808e26.tar.gz gcc-52bfec7ea0eb0f1a4c5bfa55b0d6b9b6c8808e26.tar.bz2 |
libstdc++: Check for multiple modifiers in chrono format string [PR110708]
The logic for handling modified chrono specs like %Ey was just
restarting the loop after each modifier, and not checking whether we'd
already seen a modifier.
libstdc++-v3/ChangeLog:
PR libstdc++/110708
* include/bits/chrono_io.h (__formatter_chrono::_M_parse): Only
allow a single modifier.
* testsuite/std/time/format.cc: Check multiple modifiers.
-rw-r--r-- | libstdc++-v3/include/bits/chrono_io.h | 5 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/std/time/format.cc | 10 |
2 files changed, 15 insertions, 0 deletions
diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index 87caa30..5f06a6d 100644 --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -426,6 +426,11 @@ namespace __format break; case 'O': case 'E': + if (__mod) [[unlikely]] + { + __allowed_mods = _Mod_none; + break; + } __mod = __c; continue; default: diff --git a/libstdc++-v3/testsuite/std/time/format.cc b/libstdc++-v3/testsuite/std/time/format.cc index b05e5da..0dc45d5 100644 --- a/libstdc++-v3/testsuite/std/time/format.cc +++ b/libstdc++-v3/testsuite/std/time/format.cc @@ -68,6 +68,16 @@ test_bad_format_strings() // modifier not valid for conversion specifier VERIFY( not is_format_string_for("{:%Ea}", t) ); VERIFY( not is_format_string_for("{:%Oa}", t) ); + + // more than one modifier (PR libstdc++/110708) + VERIFY( not is_format_string_for("{:%EEc}", t) ); + VERIFY( not is_format_string_for("{:%EEEc}", t) ); + VERIFY( not is_format_string_for("{:%OOd}", t) ); + VERIFY( not is_format_string_for("{:%OOOd}", t) ); + VERIFY( not is_format_string_for("{:%EEy}", t) ); + VERIFY( not is_format_string_for("{:%OOy}", t) ); + VERIFY( not is_format_string_for("{:%OEy}", t) ); + VERIFY( not is_format_string_for("{:%EOy}", t) ); } template<typename I> |