From 25979f154b47e0c64183e743d9dc2d166e2db397 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Mon, 18 Nov 2024 13:05:56 +0100 Subject: [PATCH] Make macros::expand_numeric return int64_t While we can't change the C API there is really no reason to add a new 32 bit API. Changing now while it is still internal. Emit a warning if value doesn't fit into an int for the old API and clamp at INT_MIN and INT_MAX. --- rpmio/macro.cc | 17 ++++++++++++----- rpmio/rpmmacro_internal.hh | 4 ++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/rpmio/macro.cc b/rpmio/macro.cc index 6063b85f95..7ee3b9ab00 100644 --- a/rpmio/macro.cc +++ b/rpmio/macro.cc @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include @@ -1995,7 +1997,12 @@ rpmExpandNumeric(const char *arg) if (arg == NULL) return 0; auto [ ign, val ] = macros().expand_numeric(arg); - return val; + int res = std::clamp(val, (int64_t) INT_MIN, (int64_t) INT_MAX); + if (res != val) + rpmlog(RPMLOG_WARNING, _("macro value out of range for int: %" + PRIu64 " using %i instead.\n"), val, res); + + return res; } void macros::clear() @@ -2063,12 +2070,12 @@ macros::expand_this(const char *n, ARGV_const_t args, int flags) return std::make_pair(rc, target); } -std::pair +std::pair macros::expand_numeric(const std::string & src, int flags) { auto [ exrc, s ] = macros().expand(src, flags); const char *val = s.c_str(); - int rc = 0; + int64_t rc = 0; if (!(val && *val != '%')) rc = 0; else if (*val == 'Y' || *val == 'y') @@ -2077,14 +2084,14 @@ macros::expand_numeric(const std::string & src, int flags) rc = 0; else { char *end; - rc = strtol(val, &end, 0); + rc = strtoll(val, &end, 0); if (!(end && *end == '\0')) rc = 0; } return std::make_pair(exrc, rc); } -std::pair +std::pair macros::expand_numeric(const std::initializer_list & src, int flags) { string buf; diff --git a/rpmio/rpmmacro_internal.hh b/rpmio/rpmmacro_internal.hh index 3970ddbaa0..c0c0b498e9 100644 --- a/rpmio/rpmmacro_internal.hh +++ b/rpmio/rpmmacro_internal.hh @@ -66,8 +66,8 @@ public: std::pair expand_this(const char *n, ARGV_const_t args, int flags = 0); /* Expand macros to numeric value, with a return code (rc, number) */ - std::pair expand_numeric(const std::string & src, int flags = 0); - std::pair expand_numeric(const std::initializer_list & src, + std::pair expand_numeric(const std::string & src, int flags = 0); + std::pair expand_numeric(const std::initializer_list & src, int flags = 0); void init(const char *macrofiles); bool is_defined(const char *n);