mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 22:03:03 +01:00
Backported fix for CORE-1692: Firebird::string::vprintf() fails with long resulting string
This commit is contained in:
parent
1877584537
commit
42be05407a
16
configure.in
16
configure.in
@ -470,6 +470,22 @@ if test "$EDITLINE_FLG" = "Y"; then
|
|||||||
XE_APPEND(-l$TERMLIB, LIBS)
|
XE_APPEND(-l$TERMLIB, LIBS)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl check for va_copy() in stdarg.h
|
||||||
|
dnl _ISOC99_SOURCE is defined to emulate C++ compilation in plain-C conftest.c
|
||||||
|
AC_TRY_COMPILE([#define _ISOC99_SOURCE 1
|
||||||
|
#include <stdarg.h>
|
||||||
|
void vafun(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list par, par2;
|
||||||
|
va_start(par, fmt);
|
||||||
|
va_copy(par2, par);
|
||||||
|
va_end(par2);
|
||||||
|
va_end(par);
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[exit(0);],
|
||||||
|
[AC_DEFINE(HAVE_VA_COPY, 1,
|
||||||
|
[Define this if va_copy() is defined in stdarg.h])])
|
||||||
|
|
||||||
dnl Check for functions
|
dnl Check for functions
|
||||||
AC_CHECK_FUNCS(gettimeofday)
|
AC_CHECK_FUNCS(gettimeofday)
|
||||||
|
@ -359,23 +359,37 @@ extern "C" {
|
|||||||
va_end(params);
|
va_end(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Need macros here - va_copy()/va_end() should be called in SAME function
|
||||||
|
#ifdef HAVE_VA_COPY
|
||||||
|
#define FB_VA_COPY(to, from) va_copy(to, from)
|
||||||
|
#define FB_CLOSE_VACOPY(to) va_end(to)
|
||||||
|
#else
|
||||||
|
#define FB_VA_COPY(to, from) to = from
|
||||||
|
#define FB_CLOSE_VACOPY(to)
|
||||||
|
#endif
|
||||||
|
|
||||||
void AbstractString::vprintf(const char* format, va_list params) {
|
void AbstractString::vprintf(const char* format, va_list params) {
|
||||||
#ifndef HAVE_VSNPRINTF
|
#ifndef HAVE_VSNPRINTF
|
||||||
#error NS: I am lazy to implement version of this routine based on plain vsprintf.
|
#error NS: I am lazy to implement version of this routine based on plain vsprintf.
|
||||||
#error Please find an implementation of vsnprintf function for your platform.
|
#error Please find an implementation of vsnprintf function for your platform.
|
||||||
#error For example, consider importing library from http://www.ijs.si/software/snprintf/
|
#error For example, consider importing library from http://www.ijs.si/software/snprintf/
|
||||||
#error to Firebird src\extern repository
|
#error to Firebird extern repository
|
||||||
#endif
|
#endif
|
||||||
enum {tempsize = 256};
|
enum {tempsize = 256};
|
||||||
char temp[tempsize];
|
char temp[tempsize];
|
||||||
int l = VSNPRINTF(temp, tempsize, format, params);
|
va_list paramsCopy;
|
||||||
|
FB_VA_COPY(paramsCopy, params);
|
||||||
|
int l = VSNPRINTF(temp, tempsize, format, paramsCopy);
|
||||||
|
FB_CLOSE_VACOPY(paramsCopy);
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
size_type n = sizeof(temp);
|
size_type n = sizeof(temp);
|
||||||
while (true) {
|
while (true) {
|
||||||
n *= 2;
|
n *= 2;
|
||||||
if (n > max_length())
|
if (n > max_length())
|
||||||
n = max_length();
|
n = max_length();
|
||||||
l = VSNPRINTF(baseAssign(n), n + 1, format, params);
|
FB_VA_COPY(paramsCopy, params);
|
||||||
|
l = VSNPRINTF(baseAssign(n), n + 1, format, paramsCopy);
|
||||||
|
FB_CLOSE_VACOPY(paramsCopy);
|
||||||
if (l >= 0)
|
if (l >= 0)
|
||||||
break;
|
break;
|
||||||
if (n >= max_length()) {
|
if (n >= max_length()) {
|
||||||
@ -392,7 +406,9 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
resize(l);
|
resize(l);
|
||||||
VSNPRINTF(begin(), l + 1, format, params);
|
FB_VA_COPY(paramsCopy, params);
|
||||||
|
VSNPRINTF(begin(), l + 1, format, paramsCopy);
|
||||||
|
FB_CLOSE_VACOPY(paramsCopy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user