Description
Check duplicate issues.
- Checked for duplicates
Description
Following list is not correctly reconstructed:
TList lst0;
lst0.Add(new TNamed("name0", "title0")); // without option
lst0.Add(new TNamed("name1", "title1"), ""); // with empty option
lst0.Add(new TNamed("name2", "title2"), "option2"); // with non-empty option
Problem is second element - with empty option.
In the TList it is stored as TObjOptLink
. One can change option and option is independent from the object itself.
If such TList
read from buffer, for second entry TObjLink
is created. Means option cannot be changed. And link->GetOption()
returns option from the object - which can be not empty.
Both caveats lead to problems with TPad list of primitives. If TCanvas
read from the file, suddenly draw option for histogram or for title may be changed - while instead reading empty option from TObjOptLink
some default option from histogram or from title will be returned. Also TObject::SetDrawOption()
will fail.
Related problem with JSON storage was resolved in #17198
Reproducer
TEST(TMemFile, TList_Add_Without_Option)
{
TList lst0;
lst0.Add(new TNamed("name0", "title0")); // without option
lst0.Add(new TNamed("name1", "title1"), ""); // with empty option
lst0.Add(new TNamed("name2", "title2"), "option2"); // with non-empty option
auto f = new TMemFile("test.root", "RECREATE");
f->WriteTObject(&lst0, "list");
lst0.Delete();
auto lst1 = f->Get<TList>("list");
delete f;
EXPECT_NE(lst1, nullptr);
auto link = lst1->FirstLink();
EXPECT_STREQ("name0", link->GetObject()->GetName());
EXPECT_STREQ("title0", link->GetObject()->GetTitle());
EXPECT_STREQ("", link->GetAddOption()); // by default empty string returned
EXPECT_EQ(dynamic_cast<TObjOptLink *>(link), nullptr);
link = link->Next();
EXPECT_STREQ("name1", link->GetObject()->GetName());
EXPECT_STREQ("title1", link->GetObject()->GetTitle());
EXPECT_STREQ("", link->GetAddOption());
// this line fails
EXPECT_NE(dynamic_cast<TObjOptLink *>(link), nullptr);
link = link->Next();
EXPECT_STREQ("name2", link->GetObject()->GetName());
EXPECT_STREQ("title2", link->GetObject()->GetTitle());
EXPECT_STREQ("option2", link->GetAddOption());
EXPECT_NE(dynamic_cast<TObjOptLink *>(link), nullptr);
link = link->Next();
EXPECT_EQ(link, nullptr);
}
ROOT version
master, but also ROOT versions for at least 16 years back are affected
Installation method
Build from source
Operating system
OpenSUSE Linux
Additional context
No response