Replace va_list fmt() overload with vfmt()

Using an overload that takes a va_list argument potentially causes
accidental misuse on platforms (e.g. 32-bit) where va_list is
implemented as a type that may collide with commonly-used argument
types.

For example:

    char* c = copy_string("hi");
    fmt("%s", (const char*)c);
    fmt("%s", c);

The first fmt() call correctly goes through fmt(const char*, ...) first,
but the second mistakenly goes through fmt(const char*, va_list) first
because variadic function overloads have lower priority during overload
resolution and va_list on a 32-bit system happens to be defined as a
pointer type that can match with "char*" but not "const char*".
This commit is contained in:
Jon Siwek 2020-02-14 21:26:55 -08:00
parent 8e353aafe5
commit 8fed26824b
5 changed files with 11 additions and 5 deletions

6
NEWS
View file

@ -15,6 +15,12 @@ Changed Functionality
Removed Functionality
---------------------
- The fmt() function which takes a va_list argument is replaced, use
the new vfmt() function for equivalent functionality. The former is
deprecated because overloading it with the variadic fmt() function
can cause the unintended overload to be chosen depending on how the
platform implements va_list.
Deprecated Functionality
------------------------

View file

@ -625,7 +625,7 @@ void Manager::Error(const char* format, ...)
{
va_list args;
va_start(args, format);
auto msg = fmt(format, args);
auto msg = vfmt(format, args);
va_end(args);
if ( script_scope )

View file

@ -724,7 +724,7 @@ void Stem::ReportStatus(const Supervisor::Node& node) const
void Stem::Log(std::string_view type, const char* format, va_list args) const
{
auto raw_msg = fmt(format, args);
auto raw_msg = vfmt(format, args);
if ( getenv("ZEEK_DEBUG_STEM_STDERR") )
{

View file

@ -817,7 +817,7 @@ const char* fmt_bytes(const char* data, int len)
return buf;
}
const char* fmt(const char* format, va_list al)
const char* vfmt(const char* format, va_list al)
{
static char* buf = 0;
static unsigned int buf_len = 1024;
@ -848,7 +848,7 @@ const char* fmt(const char* format, ...)
{
va_list al;
va_start(al, format);
auto rval = fmt(format, al);
auto rval = vfmt(format, al);
va_end(al);
return rval;
}

View file

@ -188,7 +188,7 @@ extern std::string strtolower(const std::string& s);
extern const char* fmt_bytes(const char* data, int len);
// Note: returns a pointer into a shared buffer.
extern const char* fmt(const char* format, va_list args);
extern const char* vfmt(const char* format, va_list args);
// Note: returns a pointer into a shared buffer.
extern const char* fmt(const char* format, ...)
__attribute__((format (printf, 1, 2)));