Bug Summary

File:mva/interface/src/Weightfile.cc
Warning:line 104, column 29
The parameter must not be null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -O3 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Weightfile.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/data/b2soft/buildbot/development/build -fcoverage-compilation-dir=/data/b2soft/buildbot/development/build -resource-dir /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/lib/clang/21 -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/c++ -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/c++/x86_64-redhat-linux -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/c++/backward -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/python3.12 -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/CLHEP -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/Geant4 -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/root -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/belle_legacy -I include/ -D _PACKAGE_="mva" -D G4UI_USE_TCSH -D RaveDllExport= -D HAS_SQLITE -D HAS_CALLGRIND -I include -I /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/libxml2 -I /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/lib/python3.12/site-packages/numpy/core/include -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../include/c++ -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../include/c++/x86_64-redhat-linux -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../include/c++/backward -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-missing-braces -Wno-unused-command-line-argument -std=c++20 -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /scan_build/2026-05-31-004316-385593-1 -x c++ mva/interface/src/Weightfile.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <mva/interface/Weightfile.h>
10
11#include <mva/dataobjects/DatabaseRepresentationOfWeightfile.h>
12#include <framework/database/Database.h>
13#include <framework/database/DBImportArray.h>
14
15#include <boost/archive/iterators/base64_from_binary.hpp>
16#include <boost/archive/iterators/binary_from_base64.hpp>
17#include <boost/archive/iterators/transform_width.hpp>
18
19#include <boost/property_tree/xml_parser.hpp>
20#include <boost/algorithm/string.hpp>
21#include <boost/algorithm/string/replace.hpp>
22#include <boost/regex.hpp>
23
24#include <TFile.h>
25
26#include <sstream>
27#include <filesystem>
28
29namespace fs = std::filesystem;
30
31namespace Belle2 {
32 namespace MVA {
33
34 std::string makeSaveForDatabase(std::string str)
35 {
36 std::map<std::string, std::string> replace {
37 {" ", "__sp"},
38 };
39 for (auto& pair : replace) {
40 boost::replace_all(str, pair.first, pair.second);
41 }
42 //const static boost::regex blackList("[^a-zA-Z0-9_]");
43 //return boost::regex_replace(str, blackList, "");
44 return str;
45 }
46
47 Weightfile::~Weightfile()
48 {
49 for (auto& filename : m_filenames) {
50 if (fs::exists(filename)) {
51 if (m_remove_temporary_directories)
52 fs::remove_all(filename);
53 }
54 }
55 }
56
57 void Weightfile::addOptions(const Options& options)
58 {
59 options.save(m_pt);
60 }
61
62 void Weightfile::getOptions(Options& options) const
63 {
64 options.load(m_pt);
65 }
66
67 void Weightfile::addFeatureImportance(const std::map<std::string, float>& importance)
68 {
69 m_pt.put("number_of_importance_vars", importance.size());
70 unsigned int i = 0;
71 for (auto& pair : importance) {
72 m_pt.put(std::string("importance_key") + std::to_string(i), pair.first);
73 m_pt.put(std::string("importance_value") + std::to_string(i), pair.second);
74 ++i;
75 }
76 }
77
78 std::map<std::string, float> Weightfile::getFeatureImportance() const
79 {
80 std::map<std::string, float> importance;
81 unsigned int numberOfImportanceVars = m_pt.get<unsigned int>("number_of_importance_vars", 0);
82 for (unsigned int i = 0; i < numberOfImportanceVars; ++i) {
83 auto key = m_pt.get<std::string>(std::string("importance_key") + std::to_string(i));
84 auto value = m_pt.get<float>(std::string("importance_value") + std::to_string(i));
85 importance[key] = value;
86 }
87 return importance;
88 }
89
90 void Weightfile::addSignalFraction(float signal_fraction)
91 {
92 m_pt.put("signal_fraction", signal_fraction);
93 }
94
95 float Weightfile::getSignalFraction() const
96 {
97 return m_pt.get<float>("signal_fraction");
98 }
99
100 std::string Weightfile::generateFileName(const std::string& suffix)
101 {
102 char* directory_template = strdup((fs::temp_directory_path() / "Basf2MVA.XXXXXX").c_str());
103 auto directory = mkdtemp(directory_template);
1
Assuming that 'mkdtemp' fails
2
'directory' initialized here
104 std::string tmpfile = std::string(directory) + std::string("/weightfile") + suffix;
3
The parameter must not be null
105 m_filenames.emplace_back(directory);
106 free(directory_template);
107 return tmpfile;
108 }
109
110 void Weightfile::addFile(const std::string& identifier, const std::string& custom_weightfile)
111 {
112 // TODO Test if file is valid
113 std::ifstream in(custom_weightfile, std::ios::in | std::ios::binary);
114 addStream(identifier, in);
115 in.close();
116 }
117
118 void Weightfile::addStream(const std::string& identifier, std::istream& in)
119 {
120 using base64_t = boost::archive::iterators::base64_from_binary <
121 boost::archive::iterators::transform_width<std::string::const_iterator, 6, 8 >>;
122
123 std::string contents;
124 in.seekg(0, std::ios::end);
125 contents.resize(in.tellg());
126 in.seekg(0, std::ios::beg);
127 in.read(&contents[0], contents.size());
128 std::string enc(base64_t(contents.begin()), base64_t(contents.end()));
129
130 m_pt.put(identifier, enc);
131 }
132
133 void Weightfile::getFile(const std::string& identifier, const std::string& custom_weightfile)
134 {
135 std::ofstream out(custom_weightfile, std::ios::out | std::ios::binary);
136 out << getStream(identifier);
137 }
138
139 std::string Weightfile::getStream(const std::string& identifier) const
140 {
141 using binary_t = boost::archive::iterators::transform_width <
142 boost::archive::iterators::binary_from_base64<std::string::const_iterator>, 8, 6 >;
143
144 auto contents = m_pt.get<std::string>(identifier);
145 std::string dec(binary_t(contents.begin()), binary_t(contents.end()));
146 return dec;
147 }
148
149 void Weightfile::save(Weightfile& weightfile, const std::string& filename, const Belle2::IntervalOfValidity& iov)
150 {
151 if (filename.ends_with(".root")) {
152 return saveToROOTFile(weightfile, filename);
153 } else if (filename.ends_with(".xml")) {
154 return saveToXMLFile(weightfile, filename);
155 } else {
156 return saveToDatabase(weightfile, filename, iov);
157 }
158 }
159
160 void Weightfile::saveToROOTFile(Weightfile& weightfile, const std::string& filename)
161 {
162 std::stringstream ss;
163 Weightfile::saveToStream(weightfile, ss);
164 DatabaseRepresentationOfWeightfile database_representation_of_weightfile;
165 database_representation_of_weightfile.m_data = ss.str();
166 TFile file(filename.c_str(), "RECREATE");
167 file.WriteObject(&database_representation_of_weightfile, "Weightfile");
168 }
169
170 void Weightfile::saveToXMLFile(Weightfile& weightfile, const std::string& filename)
171 {
172#if BOOST_VERSION109000 < 105600
173 boost::property_tree::xml_writer_settings<char> settings('\t', 1);
174#else
175 boost::property_tree::xml_writer_settings<std::string> settings('\t', 1);
176#endif
177 boost::property_tree::xml_parser::write_xml(filename, weightfile.m_pt, std::locale(), settings);
178 }
179
180 void Weightfile::saveToStream(Weightfile& weightfile, std::ostream& stream)
181 {
182#if BOOST_VERSION109000 < 105600
183 boost::property_tree::xml_writer_settings<char> settings('\t', 1);
184#else
185 boost::property_tree::xml_writer_settings<std::string> settings('\t', 1);
186#endif
187 boost::property_tree::xml_parser::write_xml(stream, weightfile.m_pt, settings);
188 }
189
190 Weightfile Weightfile::load(const std::string& filename, const Belle2::EventMetaData& emd)
191 {
192 if (filename.ends_with(".root")) {
193 return loadFromROOTFile(filename);
194 } else if (filename.ends_with(".xml")) {
195 return loadFromXMLFile(filename);
196 } else {
197 return loadFromDatabase(filename, emd);
198 }
199 }
200
201 Weightfile Weightfile::loadFromFile(const std::string& filename)
202 {
203 if (filename.ends_with(".root")) {
204 return loadFromROOTFile(filename);
205 } else if (filename.ends_with(".xml")) {
206 return loadFromXMLFile(filename);
207 } else {
208 throw std::runtime_error("Cannot load file " + filename + " because file extension is not supported");
209 }
210 }
211
212 Weightfile Weightfile::loadFromROOTFile(const std::string& filename)
213 {
214
215 if (not fs::exists(filename)) {
216 throw std::runtime_error("Given filename does not exist: " + filename);
217 }
218
219 TFile file(filename.c_str(), "READ");
220 if (file.IsZombie() or not file.IsOpen()) {
221 throw std::runtime_error("Error during open of ROOT file named " + filename);
222 }
223
224 DatabaseRepresentationOfWeightfile* database_representation_of_weightfile = nullptr;
225 file.GetObject("Weightfile", database_representation_of_weightfile);
226
227 if (database_representation_of_weightfile == nullptr) {
228 throw std::runtime_error("The provided ROOT file " + filename + " does not contain a valid MVA weightfile.");
229 }
230 std::stringstream ss(database_representation_of_weightfile->m_data);
231 delete database_representation_of_weightfile;
232 return Weightfile::loadFromStream(ss);
233 }
234
235 Weightfile Weightfile::loadFromXMLFile(const std::string& filename)
236 {
237 if (not fs::exists(filename)) {
238 throw std::runtime_error("Given filename does not exist: " + filename);
239 }
240
241 Weightfile weightfile;
242 boost::property_tree::xml_parser::read_xml(filename, weightfile.m_pt);
243 return weightfile;
244 }
245
246 Weightfile Weightfile::loadFromStream(std::istream& stream)
247 {
248 Weightfile weightfile;
249 boost::property_tree::xml_parser::read_xml(stream, weightfile.m_pt);
250 return weightfile;
251 }
252
253 void Weightfile::saveToDatabase(Weightfile& weightfile, const std::string& identifier, const Belle2::IntervalOfValidity& iov)
254 {
255 std::stringstream ss;
256 Weightfile::saveToStream(weightfile, ss);
257 DatabaseRepresentationOfWeightfile database_representation_of_weightfile;
258 database_representation_of_weightfile.m_data = ss.str();
259 Belle2::Database::Instance().storeData(makeSaveForDatabase(identifier), &database_representation_of_weightfile, iov);
260 }
261
262 void Weightfile::saveArrayToDatabase(const std::vector<Weightfile>& weightfiles, const std::string& identifier,
263 const Belle2::IntervalOfValidity& iov)
264 {
265 DBImportArray<DatabaseRepresentationOfWeightfile> dbArray(makeSaveForDatabase(identifier));
266
267 for (auto weightfile : weightfiles) {
268 std::stringstream ss;
269 Weightfile::saveToStream(weightfile, ss);
270 dbArray.appendNew(ss.str());
271 }
272
273 dbArray.import(iov);
274 }
275
276 Weightfile Weightfile::loadFromDatabase(const std::string& identifier, const Belle2::EventMetaData& emd)
277 {
278 auto pair = Belle2::Database::Instance().getData(emd, makeSaveForDatabase(identifier));
279
280 if (pair.first == 0) {
281 throw std::runtime_error("Given identifier cannot be loaded from the database: " + identifier);
282 }
283
284 DatabaseRepresentationOfWeightfile database_representation_of_weightfile = *static_cast<DatabaseRepresentationOfWeightfile*>
285 (pair.first);
286 std::stringstream ss(database_representation_of_weightfile.m_data);
287 return Weightfile::loadFromStream(ss);
288 }
289
290 }
291}