diff options
author | Andy Soffer <asoffer@google.com> | 2022-10-10 14:53:27 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2022-10-10 14:54:32 -0700 |
commit | 845610e80b66aa3d834f4d1b401133919bf7fadb (patch) | |
tree | b785139b62abd6770a80d253c2ed9640d9c0a60b /absl | |
parent | a0b5e3273bf6780b83c6e7fab23a5a92d6a005b7 (diff) |
Fix a bug in StrFormat. This issue would have been caught by any compile-time
checking but can happen for incorrect formats parsed via ParsedFormat::New.
Specifically, if a user were to add length modifiers with 'v', for example the
incorrect format string "%hv", the ParsedFormat would incorrectly be allowed.
PiperOrigin-RevId: 480183817
Change-Id: I8510c13189fdf807cdaa7f2e1b7ed9fba2aaefb9
Diffstat (limited to 'absl')
-rw-r--r-- | absl/strings/internal/str_format/parser.cc | 6 | ||||
-rw-r--r-- | absl/strings/internal/str_format/parser_test.cc | 3 |
2 files changed, 6 insertions, 3 deletions
diff --git a/absl/strings/internal/str_format/parser.cc b/absl/strings/internal/str_format/parser.cc index f9bb6615..13731ee2 100644 --- a/absl/strings/internal/str_format/parser.cc +++ b/absl/strings/internal/str_format/parser.cc @@ -202,9 +202,7 @@ 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(c == 'v' && (pos - original_pos) != 1)) return nullptr; if (ABSL_PREDICT_FALSE(!tag.is_conv())) { if (ABSL_PREDICT_FALSE(!tag.is_length())) return nullptr; @@ -223,6 +221,8 @@ const char *ConsumeConversion(const char *pos, const char *const end, conv->length_mod = length_mod; } tag = GetTagForChar(c); + + if (ABSL_PREDICT_FALSE(c == 'v')) return nullptr; if (ABSL_PREDICT_FALSE(!tag.is_conv())) return nullptr; } diff --git a/absl/strings/internal/str_format/parser_test.cc b/absl/strings/internal/str_format/parser_test.cc index fe0d2963..c3e825fe 100644 --- a/absl/strings/internal/str_format/parser_test.cc +++ b/absl/strings/internal/str_format/parser_test.cc @@ -110,10 +110,13 @@ TEST_F(ConsumeUnboundConversionTest, ConsumeSpecification) { {__LINE__, "ba", "", "ba"}, // 'b' is invalid {__LINE__, "l", "", "l" }, // just length mod isn't okay {__LINE__, "d", "d", "" }, // basic + {__LINE__, "v", "v", "" }, // basic {__LINE__, "d ", "d", " " }, // leave suffix {__LINE__, "dd", "d", "d" }, // don't be greedy {__LINE__, "d9", "d", "9" }, // leave non-space suffix {__LINE__, "dzz", "d", "zz"}, // length mod as suffix + {__LINE__, "3v", "", "3v"}, // 'v' cannot have modifiers + {__LINE__, "hv", "", "hv"}, // 'v' cannot have modifiers {__LINE__, "1$*2$d", "1$*2$d", "" }, // arg indexing and * allowed. {__LINE__, "0-14.3hhd", "0-14.3hhd", ""}, // precision, width {__LINE__, " 0-+#14.3hhd", " 0-+#14.3hhd", ""}, // flags |