From: Kern Sibbald Date: Mon, 24 Dec 2007 09:44:35 +0000 (+0000) Subject: Fix seg fault Frank Sweetser reports in regression testing X-Git-Tag: Release-2.2.7~3^2~1 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=a54aa104b24a397bf60c634d8aa4addce2a515cb;p=bacula%2Fbacula Fix seg fault Frank Sweetser reports in regression testing on his systems. The problem was that the original author of bsnprintf.c did not take into account the side effects of using ++x in the argument to a #define. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/branches/Branch-2.2@6124 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/lib/bsnprintf.c b/bacula/src/lib/bsnprintf.c index e2a05f6b62..4800c3e60a 100644 --- a/bacula/src/lib/bsnprintf.c +++ b/bacula/src/lib/bsnprintf.c @@ -77,8 +77,14 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, #define fmtfp(b, c, m, f, min, max, fl) currlen #endif -#define outch(c) {if (currlen < maxlen) { buffer[currlen++] = (c);}} - +/* + * NOTE!!!! do not use this #define with a construct such + * as outch(--place);. It just will NOT work, because the + * decrement of place is done ONLY if there is room in the + * output buffer. + */ +#define outch(c) {int len=currlen; if (currlen < maxlen) \ + { buffer[len] = (c); currlen++; }} /* format read states */ #define DP_S_DEFAULT 0 @@ -102,7 +108,7 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, /* Conversion Flags */ #define DP_C_INT16 1 -#define DP_C_INT32 2 +#define DP_C_INT32 2 #define DP_C_LDOUBLE 3 #define DP_C_INT64 4 @@ -320,7 +326,8 @@ int bvsnprintf(char *buffer, int32_t maxlen, const char *format, va_list args) currlen = fmtfp(buffer, currlen, maxlen, fvalue, min, max, flags); break; case 'c': - outch(va_arg(args, int)); + ch = va_arg(args, int); + outch(ch); break; case 's': strvalue = va_arg(args, char *); @@ -400,6 +407,7 @@ static int32_t fmtstr(char *buffer, int32_t currlen, int32_t maxlen, { int padlen, strln; /* amount to pad */ int cnt = 0; + char ch; if (flags & DP_F_DOT && max < 0) { /* Max not specified */ @@ -427,7 +435,8 @@ static int32_t fmtstr(char *buffer, int32_t currlen, int32_t maxlen, --padlen; } while (*value && (cnt < max)) { - outch(*value++); + ch = *value++; + outch(ch); ++cnt; } while (padlen < 0) { @@ -519,9 +528,10 @@ static int32_t fmtint(char *buffer, int32_t currlen, int32_t maxlen, } } - /* Digits */ + /* Output digits backward giving correct order */ while (place > 0) { - outch(convert[--place]); + place--; + outch(convert[place]); } /* Left Justified spaces */ @@ -574,8 +584,8 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, int signvalue = 0; LDOUBLE ufvalue; #ifndef HAVE_FCVT - char iconvert[20]; - char fconvert[20]; + char iconvert[25]; + char fconvert[25]; #else char iconvert[311]; char fconvert[311]; @@ -644,9 +654,10 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, iconvert[iplace++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")[intpart % 10]; intpart = (intpart / 10); - } while (intpart && (iplace < 20)); - if (iplace == 20) + } while (intpart && (iplace < (int)sizeof(iplace))); + if (iplace == (int)sizeof(iplace)) { iplace--; + } iconvert[iplace] = 0; /* Convert fractional part */ @@ -654,13 +665,15 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, fconvert[fplace++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")[fracpart % 10]; fracpart = (fracpart / 10); - } while (fracpart && (fplace < 20)); - if (fplace == 20) + } while (fracpart && (fplace < (int)sizeof(fplace))); + if (fplace == (int)sizeof(fplace)) { fplace--; + } fconvert[fplace] = 0; #else /* use fcvt() */ - if (max > 310) + if (max > 310) { max = 310; + } # ifdef HAVE_FCVTL result = fcvtl(ufvalue, max, &dec_pt, &sig); # else @@ -749,7 +762,8 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, } while (iplace > 0) { - outch(iconvert[--iplace]); + iplace--; + outch(iconvert[iplace]); } @@ -764,7 +778,8 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, if (max > 0) { outch('.'); while (fplace > 0) { - outch(fconvert[--fplace]); + fplace--; + outch(fconvert[fplace]); } } diff --git a/bacula/technotes-2.1 b/bacula/technotes-2.1 index a47573a231..1e425949ff 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -1,10 +1,11 @@ Technical notes on version 2.2 General: -23Dec07 -kes Attempt to eliminate seg fault Frank Sweetser is seeing in - running the regression tests on his Fedora systems. It seems - to be related to bsnprintf and long path names. +24Dec07 +kes Fix seg fault Frank Sweetser reports in regression testing + on his systems. The problem was that the original author of + bsnprintf.c did not take into account the side effects of + using ++x in the argument to a #define. 14Dec07 kes Apply patch from Michael Stapelberg that implements double quoting include names in conf files,