From 2c094f5559126ad7894117761fdb75a1ec4006f0 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Thu, 13 Apr 2017 13:24:57 -0400 Subject: [PATCH] Restrict parse of %Z to valid timezone names and abbrev. --- date.h | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/date.h b/date.h index 2f6a4ea..e0ded06 100644 --- a/date.h +++ b/date.h @@ -6134,7 +6134,32 @@ from_stream(std::basic_istream& is, const CharT* fmt, if (command) { if (modified == CharT{}) - is >> temp_abbrev; + { + if (!temp_abbrev.empty()) + is.setstate(ios::failbit); + else + { + while (is.rdstate() == std::ios::goodbit) + { + auto i = is.rdbuf()->sgetc(); + if (Traits::eq_int_type(i, Traits::eof())) + { + is.setstate(ios::eofbit); + break; + } + auto C = Traits::to_char_type(i); + auto c = static_cast(C); + // is c a valid time zone name or abbreviation character? + if (!(CharT{1} < C && C < CharT{127}) || !(isalnum(c) || + c == '_' || c == '/' || c == '-' || c == '+')) + break; + temp_abbrev.push_back(c); + is.rdbuf()->sbumpc(); + } + if (temp_abbrev.empty()) + is.setstate(ios::failbit); + } + } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr;