diff options
author | Abseil Team <absl-team@google.com> | 2022-09-20 13:24:16 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2022-09-20 13:25:17 -0700 |
commit | 55996e2e30cd0dc3a73dbb233e8620fec1ff36bf (patch) | |
tree | b97f2a8b5b3d4f511c18df889b197afc243cb0d4 | |
parent | d859fafe1ab9edc9c04ca262d9993be82c757881 (diff) |
Explicitly disallows modifiers for use with %v.
PiperOrigin-RevId: 475636693
Change-Id: Idb7c2b9c36ad8e59f24ff7df179a207d301d9e89
-rw-r--r-- | absl/strings/internal/str_format/parser.cc | 14 | ||||
-rw-r--r-- | absl/strings/str_format_test.cc | 11 |
2 files changed, 20 insertions, 5 deletions
diff --git a/absl/strings/internal/str_format/parser.cc b/absl/strings/internal/str_format/parser.cc index 3d987334..f9bb6615 100644 --- a/absl/strings/internal/str_format/parser.cc +++ b/absl/strings/internal/str_format/parser.cc @@ -202,6 +202,10 @@ const char *ConsumeConversion(const char *pos, const char *const end, auto tag = GetTagForChar(c); + if (*(pos - 1) == 'v' && *(pos - 2) != '%') { + return nullptr; + } + if (ABSL_PREDICT_FALSE(!tag.is_conv())) { if (ABSL_PREDICT_FALSE(!tag.is_length())) return nullptr; @@ -312,11 +316,11 @@ bool ParsedFormatBase::MatchesConversions( std::initializer_list<FormatConversionCharSet> convs) const { std::unordered_set<int> used; auto add_if_valid_conv = [&](int pos, char c) { - if (static_cast<size_t>(pos) > convs.size() || - !Contains(convs.begin()[pos - 1], c)) - return false; - used.insert(pos); - return true; + if (static_cast<size_t>(pos) > convs.size() || + !Contains(convs.begin()[pos - 1], c)) + return false; + used.insert(pos); + return true; }; for (const ConversionItem &item : items_) { if (!item.is_conversion) continue; diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc index 9ef69837..2774cfed 100644 --- a/absl/strings/str_format_test.cc +++ b/absl/strings/str_format_test.cc @@ -1020,6 +1020,17 @@ TEST_F(ParsedFormatTest, RegressionMixPositional) { absl::FormatConversionCharSet::o>::New("%1$d %o"))); } +TEST_F(ParsedFormatTest, DisallowModifiersWithV) { + auto f = ParsedFormat<'v'>::New("ABC%80vDEF"); + EXPECT_EQ(f, nullptr); + + f = ParsedFormat<'v'>::New("ABC%0vDEF"); + EXPECT_EQ(f, nullptr); + + f = ParsedFormat<'v'>::New("ABC%.1vDEF"); + EXPECT_EQ(f, nullptr); +} + using FormatWrapperTest = ::testing::Test; // Plain wrapper for StrFormat. |