mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-26 23:21:11 +00:00
[Reland] Detect against invalid variant index for LibStdC++ std::variant data formatters (#69614)
This is relanding of https://github.com/llvm/llvm-project/pull/69253. `TestTemplatePackArgs.py` is passing now. https://github.com/llvm/llvm-project/pull/68012/files added new data formatters for LibStdC++ std::variant. However, this formatter can crash if std::variant's index field has invalid value (exceeds the number of template arguments). This can happen if the current IP stops at a place std::variant is not initialized yet. This patch fixes the crash by ensuring the index is a valid value and fix GetNthTemplateArgument() to make sure it is not crashing. Co-authored-by: jeffreytan81 <jeffreytan@fb.com>
This commit is contained in:
parent
ec0645939b
commit
00d3ed6dea
@ -914,6 +914,11 @@ def VariantSummaryProvider(valobj, dict):
|
||||
if index == npos_value:
|
||||
return " No Value"
|
||||
|
||||
# Invalid index can happen when the variant is not initialized yet.
|
||||
template_arg_count = data_obj.GetType().GetNumberOfTemplateArguments()
|
||||
if index >= template_arg_count:
|
||||
return " <Invalid>"
|
||||
|
||||
active_type = data_obj.GetType().GetTemplateArgumentType(index)
|
||||
return f" Active Type = {active_type.GetDisplayTypeName()} "
|
||||
|
||||
|
@ -7183,7 +7183,8 @@ GetNthTemplateArgument(const clang::ClassTemplateSpecializationDecl *decl,
|
||||
// (including the ones preceding the parameter pack).
|
||||
const auto &pack = args[last_idx];
|
||||
const size_t pack_idx = idx - last_idx;
|
||||
assert(pack_idx < pack.pack_size() && "parameter pack index out-of-bounds");
|
||||
if (pack_idx >= pack.pack_size())
|
||||
return nullptr;
|
||||
return &pack.pack_elements()[pack_idx];
|
||||
}
|
||||
|
||||
|
@ -71,3 +71,29 @@ class LibStdcxxVariantDataFormatterTestCase(TestBase):
|
||||
substrs=["v_many_types_no_value = No Value"],
|
||||
)
|
||||
"""
|
||||
|
||||
@add_test_categories(["libstdcxx"])
|
||||
def test_invalid_variant_index(self):
|
||||
"""Test LibStdC++ data formatter for std::variant with invalid index."""
|
||||
self.build()
|
||||
|
||||
(self.target, self.process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
|
||||
self, "// break here", lldb.SBFileSpec("main.cpp", False)
|
||||
)
|
||||
|
||||
lldbutil.continue_to_breakpoint(self.process, bkpt)
|
||||
|
||||
self.expect(
|
||||
"frame variable v1",
|
||||
substrs=["v1 = Active Type = int {", "Value = 12", "}"],
|
||||
)
|
||||
|
||||
var_v1 = thread.frames[0].FindVariable("v1")
|
||||
var_v1_raw_obj = var_v1.GetNonSyntheticValue()
|
||||
index_obj = var_v1_raw_obj.GetChildMemberWithName("_M_index")
|
||||
self.assertTrue(index_obj and index_obj.IsValid())
|
||||
|
||||
INVALID_INDEX = "100"
|
||||
index_obj.SetValueFromCString(INVALID_INDEX)
|
||||
|
||||
self.expect("frame variable v1", substrs=["v1 = <Invalid>"])
|
||||
|
Loading…
Reference in New Issue
Block a user