fix: Stop using ato* for string to num conversion

atoi, atof and so on have undefined behavior if anything goes wrong. We
now use strto*, but without error checking. In most places overflows and
the like *should* not happen. String to number conversions are only used
when reading data from other applications or from the config, if another
application gives unparsable strings or too large numbers, then most
likely there is something wrong with that application. If the error
comes from the user config, then the user has to live with values
provided by strto* on error (which are very reasonable)

Fixes #1201
This commit is contained in:
patrick96 2018-04-30 18:45:01 +02:00 committed by NBonaparte
parent cc334e5040
commit 095d68fad0
10 changed files with 22 additions and 22 deletions

View File

@ -248,23 +248,23 @@ bar::bar(connection& conn, signal_emitter& emitter, const config& config, const
auto offsetx = m_conf.get(m_conf.section(), "offset-x", ""s); auto offsetx = m_conf.get(m_conf.section(), "offset-x", ""s);
auto offsety = m_conf.get(m_conf.section(), "offset-y", ""s); auto offsety = m_conf.get(m_conf.section(), "offset-y", ""s);
m_opts.size.w = atoi(w.c_str()); m_opts.size.w = std::strtol(w.c_str(), nullptr, 10);
m_opts.size.h = atoi(h.c_str()); m_opts.size.h = std::strtol(h.c_str(), nullptr, 10);
m_opts.offset.x = atoi(offsetx.c_str()); m_opts.offset.x = std::strtol(offsetx.c_str(), nullptr, 10);
m_opts.offset.y = atoi(offsety.c_str()); m_opts.offset.y = std::strtol(offsety.c_str(), nullptr, 10);
// Evaluate percentages // Evaluate percentages
double tmp; double tmp;
if ((tmp = atof(w.c_str())) && w.find('%') != string::npos) { if ((tmp = strtof(w.c_str(), nullptr)) && w.find('%') != string::npos) {
m_opts.size.w = math_util::percentage_to_value<double>(tmp, m_opts.monitor->w); m_opts.size.w = math_util::percentage_to_value<double>(tmp, m_opts.monitor->w);
} }
if ((tmp = atof(h.c_str())) && h.find('%') != string::npos) { if ((tmp = strtof(h.c_str(), nullptr)) && h.find('%') != string::npos) {
m_opts.size.h = math_util::percentage_to_value<double>(tmp, m_opts.monitor->h); m_opts.size.h = math_util::percentage_to_value<double>(tmp, m_opts.monitor->h);
} }
if ((tmp = atof(offsetx.c_str())) != 0 && offsetx.find('%') != string::npos) { if ((tmp = strtof(offsetx.c_str(), nullptr)) != 0 && offsetx.find('%') != string::npos) {
m_opts.offset.x = math_util::percentage_to_value<double>(tmp, m_opts.monitor->w); m_opts.offset.x = math_util::percentage_to_value<double>(tmp, m_opts.monitor->w);
} }
if ((tmp = atof(offsety.c_str())) != 0 && offsety.find('%') != string::npos) { if ((tmp = strtof(offsety.c_str(), nullptr)) != 0 && offsety.find('%') != string::npos) {
m_opts.offset.y = math_util::percentage_to_value<double>(tmp, m_opts.monitor->h); m_opts.offset.y = math_util::percentage_to_value<double>(tmp, m_opts.monitor->h);
} }

View File

@ -123,7 +123,7 @@ void builder::node(string str, bool add_space) {
s.erase(0, 5); s.erase(0, 5);
} else if ((n = s.find("%{T")) == 0 && (m = s.find('}')) != string::npos) { } else if ((n = s.find("%{T")) == 0 && (m = s.find('}')) != string::npos) {
font(atoi(s.substr(n + 3, m - 3).c_str())); font(strtol(s.substr(n + 3, m - 3).c_str(), nullptr, 10));
s.erase(n, m + 1); s.erase(n, m + 1);
} else if ((n = s.find("%{U-}")) == 0) { } else if ((n = s.find("%{U-}")) == 0) {

View File

@ -226,12 +226,12 @@ char config::convert(string&& value) const {
template <> template <>
int config::convert(string&& value) const { int config::convert(string&& value) const {
return std::atoi(value.c_str()); return std::strtol(value.c_str(), nullptr, 10);
} }
template <> template <>
short config::convert(string&& value) const { short config::convert(string&& value) const {
return static_cast<short>(std::atoi(value.c_str())); return static_cast<short>(std::strtol(value.c_str(), nullptr, 10));
} }
template <> template <>

View File

@ -106,7 +106,7 @@ void parser::codeblock(string&& data, const bar_settings& bar) {
break; break;
case 'O': case 'O':
m_sig.emit(offset_pixel{static_cast<int>(std::atoi(value.c_str()))}); m_sig.emit(offset_pixel{static_cast<int>(std::strtol(value.c_str(), nullptr, 10))});
break; break;
case 'l': case 'l':

View File

@ -153,7 +153,7 @@ renderer::renderer(
string pattern{f}; string pattern{f};
size_t pos = pattern.rfind(';'); size_t pos = pattern.rfind(';');
if (pos != string::npos) { if (pos != string::npos) {
offset = std::atoi(pattern.substr(pos + 1).c_str()); offset = std::strtol(pattern.substr(pos + 1).c_str(), nullptr, 10);
pattern.erase(pos); pattern.erase(pos);
} }
auto font = cairo::make_font(*m_context, string{pattern}, offset, dpi_x, dpi_y); auto font = cairo::make_font(*m_context, string{pattern}, offset, dpi_x, dpi_y);

View File

@ -69,7 +69,7 @@ int main(int argc, char** argv) {
log(E_INVALID_CHANNEL, "No channel available for pid " + args[1]); log(E_INVALID_CHANNEL, "No channel available for pid " + args[1]);
} }
pid = atoi(args[1].c_str()); pid = strtol(args[1].c_str(), nullptr, 10);
args.erase(args.begin()); args.erase(args.begin());
args.erase(args.begin()); args.erase(args.begin());
} }

View File

@ -76,7 +76,7 @@ namespace modules {
auto spacing = m_formatter->get(get_format())->spacing; auto spacing = m_formatter->get(get_format())->spacing;
for (auto&& item : m_levels[m_level]->items) { for (auto&& item : m_levels[m_level]->items) {
/* /*
* Depending on whether the menu items are to the left or right of the toggle label, the items need to be * Depending on whether the menu items are to the left or right of the toggle label, the items need to be
* drawn before or after the spacings and the separator * drawn before or after the spacings and the separator
* *
* If the menu expands to the left, the separator should be drawn on the right side because otherwise the menu * If the menu expands to the left, the separator should be drawn on the right side because otherwise the menu
@ -132,7 +132,7 @@ namespace modules {
if (level.empty()) { if (level.empty()) {
level = "0"; level = "0";
} }
m_level = std::atoi(level.c_str()); m_level = std::strtol(level.c_str(), nullptr, 10);
m_log.info("%s: Opening menu level '%i'", name(), static_cast<int>(m_level)); m_log.info("%s: Opening menu level '%i'", name(), static_cast<int>(m_level));
if (static_cast<size_t>(m_level) >= m_levels.size()) { if (static_cast<size_t>(m_level) >= m_levels.size()) {

View File

@ -368,11 +368,11 @@ namespace modules {
if (s.empty()) { if (s.empty()) {
return false; return false;
} else if (s[0] == '+') { } else if (s[0] == '+') {
percentage = status->get_elapsed_percentage() + std::atoi(s.substr(1).c_str()); percentage = status->get_elapsed_percentage() + std::strtol(s.substr(1).c_str(), nullptr, 10);
} else if (s[0] == '-') { } else if (s[0] == '-') {
percentage = status->get_elapsed_percentage() - std::atoi(s.substr(1).c_str()); percentage = status->get_elapsed_percentage() - std::strtol(s.substr(1).c_str(), nullptr, 10);
} else { } else {
percentage = std::atoi(s.c_str()); percentage = std::strtol(s.c_str(), nullptr, 10);
} }
mpd->seek(status->get_songid(), status->get_seek_position(percentage)); mpd->seek(status->get_songid(), status->get_seek_position(percentage));
} else { } else {

View File

@ -50,7 +50,7 @@ namespace modules {
} }
bool temperature_module::update() { bool temperature_module::update() {
m_temp = std::atoi(file_util::contents(m_path).c_str()) / 1000.0f + 0.5f; m_temp = std::strtol(file_util::contents(m_path).c_str(), nullptr, 10) / 1000.0f + 0.5f;
int m_temp_f = floor(((1.8 * m_temp) + 32) + 0.5); int m_temp_f = floor(((1.8 * m_temp) + 32) + 0.5);
m_perc = math_util::cap(math_util::percentage(m_temp, 0, m_tempwarn), 0, 100); m_perc = math_util::cap(math_util::percentage(m_temp, 0, m_tempwarn), 0, 100);

View File

@ -144,8 +144,8 @@ void tray_manager::setup(const bar_settings& bar_opts) {
auto offset_x_def = conf.get(bs, "tray-offset-x", ""s); auto offset_x_def = conf.get(bs, "tray-offset-x", ""s);
auto offset_y_def = conf.get(bs, "tray-offset-y", ""s); auto offset_y_def = conf.get(bs, "tray-offset-y", ""s);
auto offset_x = atoi(offset_x_def.c_str()); auto offset_x = strtol(offset_x_def.c_str(), nullptr, 10);
auto offset_y = atoi(offset_y_def.c_str()); auto offset_y = strtol(offset_y_def.c_str(), nullptr, 10);
if (offset_x != 0 && offset_x_def.find('%') != string::npos) { if (offset_x != 0 && offset_x_def.find('%') != string::npos) {
if (m_opts.detached) { if (m_opts.detached) {