Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Replace local dependent string functions with non-locale versions in strencodings.h/cpp #2270

Merged
merged 17 commits into from
Aug 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/bignum.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,11 @@ class CBigNum : public CBigNumBase
psz++;

// hex string to bignum
static const signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
*this = 0;
while (isxdigit(*psz))
while (HexDigit(*psz) >= 0)
{
*this <<= 4;
int n = phexdigit[(unsigned char)*psz++];
int n = HexDigit((unsigned char)*psz++);
*this += n;
}
if (fNegative)
Expand Down
11 changes: 7 additions & 4 deletions src/gridcoin/accrual/snapshot.h
Original file line number Diff line number Diff line change
Expand Up @@ -552,11 +552,14 @@ class AccrualSnapshotFile
//!
static uint64_t ParseHeight(const fs::path& snapshot_path)
{
try {
return std::stoull(snapshot_path.stem().string());
} catch (...) {
return 0;
uint64_t height = 0;

if (!ParseUInt64(snapshot_path.stem().string(), &height)) {
LogPrint(BCLog::LogFlags::SB, "WARN: %s: Filename in snapshot path does not contain a valid height number.",
__func__);
}

return height;
}

//!
Expand Down
19 changes: 12 additions & 7 deletions src/gridcoin/researcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ bool UpdateRWSettingsForMode(const ResearcherMode mode, const std::string& email
//!
std::string LowerUnderscore(std::string data)
{
boost::to_lower(data);
data = ToLower(data);
boost::replace_all(data, "_", " ");

return data;
Expand Down Expand Up @@ -304,7 +304,7 @@ std::set<std::string> GetTeamWhitelist()
continue;
}

boost::to_lower(team_name);
team_name = ToLower(team_name);

teams.emplace(std::move(team_name));
}
Expand Down Expand Up @@ -794,18 +794,23 @@ MiningProject::MiningProject(std::string name,
, m_rac(std::move(rac))
, m_error(Error::NONE)
{
boost::to_lower(m_team);
m_team = ToLower(m_team);
}

MiningProject MiningProject::Parse(const std::string& xml)
{
double rac = 0.0;

if (!ParseDouble(ExtractXML(xml, "<user_expavg_credit>", "</user_expavg_credit>"), &rac)) {
LogPrintf("WARN: %s: Unable to parse user RAC from legacy XML data.", __func__);
}

MiningProject project(
ExtractXML(xml, "<project_name>", "</project_name>"),
Cpid::Parse(ExtractXML(xml, "<external_cpid>", "</external_cpid>")),
ExtractXML(xml, "<team_name>", "</team_name>"),
ExtractXML(xml, "<master_url>", "</master_url>"),
std::strtold(ExtractXML(xml, "<user_expavg_credit>",
"</user_expavg_credit>").c_str(), nullptr));
rac);

if (IsPoolCpid(project.m_cpid) && !gArgs.GetBoolArg("-pooloperator", false)) {
project.m_error = MiningProject::Error::POOL;
Expand Down Expand Up @@ -1101,7 +1106,7 @@ std::string Researcher::Email()
if (gArgs.GetBoolArg("-investor", false)) return email;

email = gArgs.GetArg("-email", "");
boost::to_lower(email);
email = ToLower(email);

return email;
}
Expand Down Expand Up @@ -1348,7 +1353,7 @@ GRC::BeaconError Researcher::BeaconError() const

bool Researcher::ChangeMode(const ResearcherMode mode, std::string email)
{
boost::to_lower(email);
email = ToLower(email);

if (mode == ResearcherMode::INVESTOR && ConfiguredForInvestorMode()) {
return true;
Expand Down
4 changes: 2 additions & 2 deletions src/gridcoin/scraper/http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,10 @@ namespace
}

constexpr char expected[] = "etag";
constexpr int32_t to_upper = 32;
constexpr int32_t shift_to_upper = 32;

for (size_t i = 0; i < 4; ++i) {
if (header[i] != expected[i] && header[i] != expected[i] - to_upper) {
if (header[i] != expected[i] && header[i] != expected[i] - shift_to_upper) {
return std::string();
}
}
Expand Down
138 changes: 109 additions & 29 deletions src/gridcoin/scraper/scraper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -878,24 +878,59 @@ void ApplyCache(const std::string& key, T& result)
try
{
if (std::is_same<T, double>::value)
result = stod(entry.value);
{
double out = 0.0;

if (!ParseDouble(entry.value, &out))
{
throw std::invalid_argument("Argument is not parseable as a double.");
}

// Have to do the copy here and below, because otherwise the compiler complains about putting &result directly
// above, since this is a template.
result = out;
}
else if (std::is_same<T, int64_t>::value)
result = atoi64(entry.value);
{
int64_t out = 0;

if (!ParseInt64(entry.value, &out))
{
throw std::invalid_argument("Argument is not parseable as an int64_t.");
}

result = out;
}
else if (std::is_same<T, unsigned int>::value)
// Throw away (zero out) negative integer
// This approach limits the range to the non-negative signed int, but that is good enough.
result = (unsigned int)std::max(0, stoi(entry.value));
{
unsigned int out = 0;

if (!ParseUInt(entry.value, &out))
{
throw std::invalid_argument("Argument is not parseable as an unsigned int.");
}

result = out;
}
else if (std::is_same<T, bool>::value)
{
if (entry.value == "false" || entry.value == "0")
{
result = boost::lexical_cast<T>(false);
}
else if (entry.value == "true" || entry.value == "1")
{
result = boost::lexical_cast<T>(true);
}
else
{
throw std::invalid_argument("Argument not true or false");
}
}
else
{
result = boost::lexical_cast<T>(entry.value);
}
}
catch (const std::exception&)
{
Expand Down Expand Up @@ -1879,20 +1914,18 @@ bool ProcessProjectTeamFile(const std::string& project, const fs::path& file, co

int64_t nTeamID = 0;

try
{
nTeamID = atoi64(sTeamID);
}
catch (const std::exception&)
if (!ParseInt64(sTeamID, &nTeamID))
{
_log(logattribute::ERR, "ProccessProjectTeamFile", tfm::format("Ignoring bad team id for team %s.", sTeamName));
_log(logattribute::ERR, __func__, tfm::format("Ignoring bad team id for team %s.", sTeamName));
continue;
}

mTeamIdsForProject[sTeamName] = nTeamID;
}
else
{
builder.append(line);
}
}

if (mTeamIdsForProject.empty())
Expand Down Expand Up @@ -2284,13 +2317,9 @@ bool ProcessProjectRacFileByCPID(const std::string& project, const fs::path& fil
const std::string& sTeamID = ExtractXML(data, "<teamid>", "</teamid>");
int64_t nTeamID = 0;

try
if (!ParseInt64(sTeamID, &nTeamID))
{
nTeamID = atoi64(sTeamID);
}
catch (const std::exception&)
{
_log(logattribute::ERR, "ProcessProjectRacFileByCPID", "Bad team id in user stats file data.");
_log(logattribute::ERR, __func__, "Bad team id in user stats file data.");
continue;
}

Expand Down Expand Up @@ -2550,13 +2579,9 @@ bool LoadTeamIDList(const fs::path& file)
sProject = iter;
else
{
try
{
nTeamID = atoi64(iter);
}
catch (std::exception&)
if (!ParseInt64(iter, &nTeamID))
{
_log(logattribute::ERR, "LoadTeamIDList", "Ignoring invalid team id found in team id file.");
_log(logattribute::ERR, __func__, "Ignoring invalid team id found in team id file.");
continue;
}

Expand Down Expand Up @@ -2898,7 +2923,16 @@ bool LoadScraperFileManifest(const fs::path& file)
nhash.SetHex(vline[0].c_str());
LoadEntry.hash = nhash;

LoadEntry.current = std::stoi(vline[1]);
// We will use the ParseUInt from strencodings to avoid the locale specific stoi.
unsigned int parsed_current = 0;

if (!ParseUInt(vline[1], &parsed_current))
{
_log(logattribute::ERR, __func__, "The \"current\" field not parsed correctly for a manifest entry. Skipping.");
continue;
}

LoadEntry.current = parsed_current;

std::istringstream sstimestamp(vline[2]);
sstimestamp >> ntimestamp;
Expand All @@ -2913,7 +2947,17 @@ bool LoadScraperFileManifest(const fs::path& file)
{
// Intended for explorer mode, where files not to be included in CScraperManifest
// are to be maintained, such as team and host files.
LoadEntry.excludefromcsmanifest = std::stoi(vline[5]);
unsigned int parsed_exclude = 0;

if (!ParseUInt(vline[5], &parsed_exclude))
{
// This shouldn't happen given the conditional above, but to be thorough...
_log(logattribute::ERR, __func__, "The \"excludefromcsmanifest\" field not parsed correctly for a manifest "
"entry. Skipping.");
continue;
}

LoadEntry.excludefromcsmanifest = parsed_exclude;
}
else
{
Expand Down Expand Up @@ -3158,10 +3202,46 @@ bool ProcessProjectStatsFromStreamByCPID(const std::string& project, boostio::fi
const std::string& sRAC = fields[2];
const std::string& cpid = fields[3];

// Replace blank strings with zeros.
statsentry.statsvalue.dTC = (sTC.empty()) ? 0.0 : std::stod(sTC);
statsentry.statsvalue.dRAT = (sRAT.empty()) ? 0.0 : std::stod(sRAT);
statsentry.statsvalue.dRAC = (sRAC.empty()) ? 0.0 : std::stod(sRAC);
// Replace blank strings with zeros. Continue to next record with a logged error if there is a parsing failure.
if (sTC.empty())
{
statsentry.statsvalue.dTC = 0.0;
}
else
{
if (!ParseDouble(sTC, &statsentry.statsvalue.dTC))
{
_log(logattribute::ERR, __func__, "Cannot parse sTC " + sTC + " for cpid " + cpid);
continue;
}
}

if (sRAT.empty())
{
statsentry.statsvalue.dRAT = 0.0;
}
else
{
if (!ParseDouble(sRAT, &statsentry.statsvalue.dRAT))
{
_log(logattribute::ERR, __func__, "Cannot parse sRAT " + sRAT + " for cpid " + cpid);
continue;
}
}

if (sRAC.empty())
{
statsentry.statsvalue.dRAC = 0.0;
}
else
{
if (!ParseDouble(sRAC, &statsentry.statsvalue.dRAC))
{
_log(logattribute::ERR, __func__, "Cannot parse sRAC " + sRAC + " for cpid " + cpid);
continue;
}
}

// At the individual (byCPIDbyProject) level the AvgRAC is the same as the RAC.
statsentry.statsvalue.dAvgRAC = statsentry.statsvalue.dRAC;
// Mag is dealt with on the second pass... so is left at 0.0 on the first pass.
Expand Down
14 changes: 10 additions & 4 deletions src/gridcoin/staking/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ int64_t GetRSAWeightByBlock(const std::string& bb)
constexpr size_t rsa_weight_offset = 13;
constexpr size_t magnitude_offset = 15;

int64_t rsa_weight = 0;
int64_t rsa_weight_sum = 0;

// General-purpose deserialization of claim contexts in the hashBoinc field
// no longer parses out the RSA weight field, so we handle the special case
Expand All @@ -154,18 +154,24 @@ int64_t GetRSAWeightByBlock(const std::string& bb)
if (n == cpid_offset && end - offset != 32) {
return 0;
} else if (n == rsa_weight_offset || n == magnitude_offset) {
rsa_weight += std::atoi(bb.substr(offset, end - offset).c_str());
int64_t rsa_weight = 0;

if (!ParseInt64(bb.substr(offset, end - offset), &rsa_weight)) {
error("%s: Unable to parse rsa weight from hashBoinc.", __func__);
}

rsa_weight_sum += rsa_weight;
}

offset = end + 3;
end = bb.find("<|>", offset);
}

if (rsa_weight < 0) {
if (rsa_weight_sum < 0) {
return 0;
}

return rsa_weight;
return rsa_weight_sum;
}
} // anonymous namespace

Expand Down
7 changes: 6 additions & 1 deletion src/gridcoin/staking/reward.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ CAmount GRC::GetConstantBlockReward(const CBlockIndex* index)
//TODO: refactor the expire checking to subroutine
//Note: time constant is same as GetBeaconPublicKey
if ((index->nTime - oCBReward.timestamp) <= (60 * 24 * 30 * 6 * 60)) {
reward = atoi64(oCBReward.value);
// This is a little slippery, because if we ever change CAmount from a int64_t, this will
// break. It is unlikely to ever change, however, and avoids an extra copy/implicit cast.
if (!ParseInt64(oCBReward.value, &reward)) {
denravonska marked this conversation as resolved.
Show resolved Hide resolved
error("%s: Cannot parse constant block reward from protocol entry: %s",
__func__, oCBReward.value);
}
}

reward = std::clamp(reward, MIN_CBR, MAX_CBR);
Expand Down
Loading