Skip to content

Commit 89c64e3

Browse files
committed
Fix(dft+u): validate occupation tags and MPI counts
1 parent 3338c0f commit 89c64e3

2 files changed

Lines changed: 39 additions & 4 deletions

File tree

source/source_estate/module_charge/charge_mixing.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "charge_mixing.h"
22

33
#include <functional>
4+
#include <limits>
45

56
#include "source_io/module_parameter/parameter.h"
67
#include "source_base/module_mixing/broyden_mixing.h"
@@ -361,7 +362,11 @@ void Charge_Mixing::mix_uom(std::vector<double>& uom_in, std::vector<double>& uo
361362
#ifdef __MPI
362363
// Synchronize mixed uom across all ranks to prevent divergence
363364
// after multiple mixing steps.
364-
Parallel_Common::bcast_double(uom_in.data(), uom_in.size());
365+
if (uom_in.size() > static_cast<std::size_t>(std::numeric_limits<int>::max()))
366+
{
367+
ModuleBase::WARNING_QUIT("Charge_Mixing::mix_uom", "UOM buffer is too large for MPI broadcast count");
368+
}
369+
Parallel_Common::bcast_double(uom_in.data(), static_cast<int>(uom_in.size()));
365370
#endif
366371
return;
367372
}

source/source_pw/module_pwdft/dftu_base.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
#include "source_base/timer.h"
77
#include "source_io/module_parameter/parameter.h"
88

9-
#include <cstdlib>
109
#include <cstring>
1110
#include <fstream>
11+
#include <limits>
1212
#include <sstream>
13+
#include <stdexcept>
1314
#include <vector>
1415

1516
// local inline helpers for eigenvalue calculation (JacobiRotate, CalculateEigenvalues)
@@ -553,7 +554,32 @@ void Plus_U_Base::read_occup_m(const UnitCell& ucell,
553554
}
554555
else
555556
{
556-
value = std::atoi(token.c_str() + tag.size());
557+
const std::string number = token.substr(tag.size());
558+
if (number.empty())
559+
{
560+
return false;
561+
}
562+
563+
std::size_t consumed = 0;
564+
try
565+
{
566+
const long parsed = std::stol(number, &consumed, 10);
567+
if (consumed != number.size()
568+
|| parsed < static_cast<long>(std::numeric_limits<int>::min())
569+
|| parsed > static_cast<long>(std::numeric_limits<int>::max()))
570+
{
571+
return false;
572+
}
573+
value = static_cast<int>(parsed);
574+
}
575+
catch (const std::invalid_argument&)
576+
{
577+
return false;
578+
}
579+
catch (const std::out_of_range&)
580+
{
581+
return false;
582+
}
557583
}
558584
return static_cast<bool>(ifdftu);
559585
};
@@ -574,8 +600,12 @@ void Plus_U_Base::read_occup_m(const UnitCell& ucell,
574600
break;
575601
}
576602

577-
if (read_tagged_int(word, "Atom=", iat))
603+
if (word.compare(0, 5, "Atom=") == 0)
578604
{
605+
if (!read_tagged_int(word, "Atom=", iat) || iat < 1 || iat > ucell.nat)
606+
{
607+
ModuleBase::WARNING_QUIT("Plus_U_Base::read_occup_m", "WRONG ATOM INDEX IN LOCAL OCCUPATION NUMBER MATRIX FROM Plus_U FILE");
608+
}
579609
iat -= 1;
580610
ifdftu >> word;
581611

0 commit comments

Comments
 (0)