From: Juergen Perlinger Date: Sat, 1 Dec 2018 11:10:51 +0000 (+0100) Subject: [Bug 3556] ntp_loopfilter.c snprintf compilation warnings X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e74b4bdc9901ceecd13de6ac9468a4adb89f91ec;p=thirdparty%2Fntp.git [Bug 3556] ntp_loopfilter.c snprintf compilation warnings - provide better function for incremental string formatting bk: 5c026c3bFcFiwk5XT5kAcXgiQbNFoA --- diff --git a/ChangeLog b/ChangeLog index f381a093c..1f7c18c54 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +--- +* [Bug 3556] ntp_loopfilter.c snprintf compilation warnings + - provide better function for incremental string formatting + --- (4.2.8p12) 2018/08/14 Released by Harlan Stenn diff --git a/include/ntp_stdlib.h b/include/ntp_stdlib.h index 889c3b25e..c0bc71b09 100644 --- a/include/ntp_stdlib.h +++ b/include/ntp_stdlib.h @@ -40,6 +40,9 @@ extern void setup_logfile (const char *); extern void errno_to_str(int, char *, size_t); #endif +extern int xvsbprintf(char**, char* const, char const*, va_list) NTP_PRINTF(3, 0); +extern int xsbprintf(char**, char* const, char const*, ...) NTP_PRINTF(3, 4); + /* * When building without OpenSSL, use a few macros of theirs to * minimize source differences in NTP. diff --git a/libntp/Makefile.am b/libntp/Makefile.am index 6f3c0ba45..04b53b0cb 100644 --- a/libntp/Makefile.am +++ b/libntp/Makefile.am @@ -110,6 +110,7 @@ libntp_a_SRCS = \ vint64ops.c \ work_fork.c \ work_thread.c \ + xsbprintf.c \ ymd2yd.c \ $(libisc_SRCS) \ $(NULL) diff --git a/libntp/xsbprintf.c b/libntp/xsbprintf.c new file mode 100644 index 000000000..e7d197591 --- /dev/null +++ b/libntp/xsbprintf.c @@ -0,0 +1,77 @@ +/* + * xsbprintf.c - string buffer formatting helpers + * + * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project. + * The contents of 'html/copyright.html' apply. + */ + +#include +#include + +#include "ntp_stdlib.h" + +/* eXtended Varlist String Buffer printf + * + * Formats via 'vsnprintf' into a string buffer, with some semantic + * specialties: + * + * - The start of the buffer pointer is updated according to the number + * of characters written. + * - If the buffer is insufficient to format the number of charactes, + * the partial result will be be discarded, and zero is returned to + * indicate nothing was written to the buffer. + * - On successful formatting, the return code is the return value of + * the inner call to 'vsnprintf()'. + * - If there is any error, the state of the buffer will not be + * changed. (Bytes in the buffer might be smashed, but the buffer + * position does not change, and the NUL marker stays in place at the + * current buffer position.) + */ +int +xvsbprintf( + char **ppbuf, /* pointer to buffer pointer (I/O) */ + char * const pend, /* buffer end (I) */ + char const *pfmt, /* printf-like format string */ + va_list va /* formatting args for above */ + ) +{ + char *pbuf = (ppbuf) ? *ppbuf : NULL; + int rc = -1; + if (pbuf) { + size_t ilen = (size_t)(pend - pbuf); + if (ilen) { + *pbuf = '\0'; + rc = vsnprintf(pbuf, ilen, pfmt, va); + if (rc > 0) { + if ((size_t)rc >= ilen) + rc = 0; + pbuf += rc; + } + *pbuf = '\0'; /* fear of bad vsnprintf */ + } + *ppbuf = pbuf; + } else { + errno = EINVAL; + } + return rc; +} + +/* variadic wrapper around the buufer string formatter */ +int +xsbprintf( + char **ppbuf, /* pointer to buffer pointer (I/O) */ + char * const pend, /* buffer end (I) */ + char const *pfmt, /* printf-like format string */ + ... /* formatting args for above */ + ) +{ + va_list va; + int rc; + + va_start(va, pfmt); + rc = xvsbprintf(ppbuf, pend, pfmt, va); + va_end(va); + return rc; +} + +/* that's all folks! */ diff --git a/ntpd/ntp_loopfilter.c b/ntpd/ntp_loopfilter.c index 924d5738b..01772bd1f 100644 --- a/ntpd/ntp_loopfilter.c +++ b/ntpd/ntp_loopfilter.c @@ -246,7 +246,11 @@ ntp_adjtime_error_handler( ) { char des[1024] = ""; /* Decoded Error Status */ + char *dbp, *ebp; + dbp = des; + ebp = dbp + sizeof(des); + switch (ret) { case -1: switch (saved_errno) { @@ -363,37 +367,37 @@ or, from ntp_adjtime(): /* error (see status word) */ if (ptimex->status & STA_UNSYNC) - snprintf(des, sizeof(des), "%s%sClock Unsynchronized", - des, (*des) ? "; " : ""); + xsbprintf(&dbp, ebp, "%sClock Unsynchronized", + (*des) ? "; " : ""); if (ptimex->status & STA_CLOCKERR) - snprintf(des, sizeof(des), "%s%sClock Error", - des, (*des) ? "; " : ""); + xsbprintf(&dbp, ebp, "%sClock Error", + (*des) ? "; " : ""); if (!(ptimex->status & STA_PPSSIGNAL) && ptimex->status & STA_PPSFREQ) - snprintf(des, sizeof(des), "%s%sPPS Frequency Sync wanted but no PPS", - des, (*des) ? "; " : ""); + xsbprintf(&dbp, ebp, "%sPPS Frequency Sync wanted but no PPS", + (*des) ? "; " : ""); if (!(ptimex->status & STA_PPSSIGNAL) && ptimex->status & STA_PPSTIME) - snprintf(des, sizeof(des), "%s%sPPS Time Sync wanted but no PPS signal", - des, (*des) ? "; " : ""); + xsbprintf(&dbp, ebp, "%sPPS Time Sync wanted but no PPS signal", + (*des) ? "; " : ""); if ( ptimex->status & STA_PPSTIME && ptimex->status & STA_PPSJITTER) - snprintf(des, sizeof(des), "%s%sPPS Time Sync wanted but PPS Jitter exceeded", - des, (*des) ? "; " : ""); + xsbprintf(&dbp, ebp, "%sPPS Time Sync wanted but PPS Jitter exceeded", + (*des) ? "; " : ""); if ( ptimex->status & STA_PPSFREQ && ptimex->status & STA_PPSWANDER) - snprintf(des, sizeof(des), "%s%sPPS Frequency Sync wanted but PPS Wander exceeded", - des, (*des) ? "; " : ""); + xsbprintf(&dbp, ebp, "%sPPS Frequency Sync wanted but PPS Wander exceeded", + (*des) ? "; " : ""); if ( ptimex->status & STA_PPSFREQ && ptimex->status & STA_PPSERROR) - snprintf(des, sizeof(des), "%s%sPPS Frequency Sync wanted but Calibration error detected", - des, (*des) ? "; " : ""); + xsbprintf(&dbp, ebp, "%sPPS Frequency Sync wanted but Calibration error detected", + (*des) ? "; " : ""); if (pps_call && !(ptimex->status & STA_PPSSIGNAL)) report_event(EVNT_KERN, NULL, diff --git a/ports/winnt/vs2005/libntp.vcproj b/ports/winnt/vs2005/libntp.vcproj index e1c7b6595..312ccdac0 100644 --- a/ports/winnt/vs2005/libntp.vcproj +++ b/ports/winnt/vs2005/libntp.vcproj @@ -568,6 +568,10 @@ RelativePath="..\..\..\libntp\work_thread.c" > + + diff --git a/ports/winnt/vs2008/libntp/libntp.vcproj b/ports/winnt/vs2008/libntp/libntp.vcproj index 2057d758b..7a7b478ae 100644 --- a/ports/winnt/vs2008/libntp/libntp.vcproj +++ b/ports/winnt/vs2008/libntp/libntp.vcproj @@ -687,6 +687,10 @@ RelativePath="..\..\..\..\libntp\work_thread.c" > + + diff --git a/ports/winnt/vs2013/libntp/libntp.vcxproj b/ports/winnt/vs2013/libntp/libntp.vcxproj index 26a13c21f..3d9f295c7 100644 --- a/ports/winnt/vs2013/libntp/libntp.vcxproj +++ b/ports/winnt/vs2013/libntp/libntp.vcxproj @@ -1,4 +1,4 @@ - + @@ -277,6 +277,7 @@ + @@ -432,4 +433,4 @@ - \ No newline at end of file + diff --git a/ports/winnt/vs2013/libntp/libntp.vcxproj.filters b/ports/winnt/vs2013/libntp/libntp.vcxproj.filters index 9839bbd83..1d6a7b40f 100644 --- a/ports/winnt/vs2013/libntp/libntp.vcxproj.filters +++ b/ports/winnt/vs2013/libntp/libntp.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -320,6 +320,9 @@ Source Files + + Source Files + Source Files @@ -583,4 +586,4 @@ Resource Files - \ No newline at end of file + diff --git a/ports/winnt/vs2015/libntp/libntp.vcxproj b/ports/winnt/vs2015/libntp/libntp.vcxproj index a93e97015..0a9433f32 100644 --- a/ports/winnt/vs2015/libntp/libntp.vcxproj +++ b/ports/winnt/vs2015/libntp/libntp.vcxproj @@ -1,4 +1,4 @@ - + @@ -277,6 +277,7 @@ + @@ -432,4 +433,4 @@ - \ No newline at end of file + diff --git a/ports/winnt/vs2015/libntp/libntp.vcxproj.filters b/ports/winnt/vs2015/libntp/libntp.vcxproj.filters index 9839bbd83..1d6a7b40f 100644 --- a/ports/winnt/vs2015/libntp/libntp.vcxproj.filters +++ b/ports/winnt/vs2015/libntp/libntp.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -320,6 +320,9 @@ Source Files + + Source Files + Source Files @@ -583,4 +586,4 @@ Resource Files - \ No newline at end of file + diff --git a/tests/libntp/Makefile.am b/tests/libntp/Makefile.am index 6ebb11705..67b34e7c0 100644 --- a/tests/libntp/Makefile.am +++ b/tests/libntp/Makefile.am @@ -40,6 +40,7 @@ check_PROGRAMS = \ test-recvbuff \ test-refidsmear \ test-refnumtoa \ + test-sbprintf \ test-sfptostr \ test-socktoa \ test-ssl_init \ @@ -104,6 +105,7 @@ BUILT_SOURCES += \ $(srcdir)/run-recvbuff.c \ $(srcdir)/run-refidsmear.c \ $(srcdir)/run-refnumtoa.c \ + $(srcdir)/run-sbprintf.c \ $(srcdir)/run-sfptostr.c \ $(srcdir)/run-socktoa.c \ $(srcdir)/run-ssl_init.c \ @@ -410,6 +412,16 @@ $(srcdir)/run-refnumtoa.c: $(srcdir)/refnumtoa.c $(std_unity_list) ### +test_sbprintf_SOURCES = \ + sbprintf.c \ + run-sbprintf.c \ + $(NULL) + +$(srcdir)/run-sbprintf.c: $(srcdir)/sbprintf.c $(std_unity_list) + $(run_unity) $< $@ + +### + test_sfptostr_SOURCES = \ sfptostr.c \ run-sfptostr.c \ diff --git a/tests/libntp/run-sbprintf.c b/tests/libntp/run-sbprintf.c new file mode 100644 index 000000000..a3c1661c1 --- /dev/null +++ b/tests/libntp/run-sbprintf.c @@ -0,0 +1,72 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ + +//=======Test Runner Used To Run Each Test Below===== +#define RUN_TEST(TestFunc, TestLineNum) \ +{ \ + Unity.CurrentTestName = #TestFunc; \ + Unity.CurrentTestLineNumber = TestLineNum; \ + Unity.NumberOfTests++; \ + if (TEST_PROTECT()) \ + { \ + setUp(); \ + TestFunc(); \ + } \ + if (TEST_PROTECT() && !TEST_IS_IGNORED) \ + { \ + tearDown(); \ + } \ + UnityConcludeTest(); \ +} + +//=======Automagically Detected Files To Include===== +#include "unity.h" +#include +#include +#include "config.h" +#include "ntp_stdlib.h" +#include + +//=======External Functions This Runner Calls===== +extern void setUp(void); +extern void tearDown(void); +extern void test_NullBuf1(void); +extern void test_NullBuf2(void); +extern void test_SmallBuf(void); +extern void test_MatchBuf(void); +extern void test_BigBuf(void); +extern void test_SimpleArgs(void); + + +//=======Suite Setup===== +static void suite_setup(void) +{ +extern int change_logfile(const char*, int); +change_logfile("stderr", 0); +} + +//=======Test Reset Option===== +void resetTest(void); +void resetTest(void) +{ + tearDown(); + setUp(); +} + +char const *progname; + + +//=======MAIN===== +int main(int argc, char *argv[]) +{ + progname = argv[0]; + suite_setup(); + UnityBegin("sbprintf.c"); + RUN_TEST(test_NullBuf1, 7); + RUN_TEST(test_NullBuf2, 14); + RUN_TEST(test_SmallBuf, 23); + RUN_TEST(test_MatchBuf, 34); + RUN_TEST(test_BigBuf, 45); + RUN_TEST(test_SimpleArgs, 56); + + return (UnityEnd()); +} diff --git a/tests/libntp/sbprintf.c b/tests/libntp/sbprintf.c new file mode 100644 index 000000000..6df42639e --- /dev/null +++ b/tests/libntp/sbprintf.c @@ -0,0 +1,67 @@ +#include "config.h" +#include "ntp_stdlib.h" +#include "unity.h" + +#include + +extern void test_NullBuf1(void); +void test_NullBuf1(void) +{ + int rc = xsbprintf(NULL, NULL, "blah"); + TEST_ASSERT(rc == -1 && errno == EINVAL); +} + +extern void test_NullBuf2(void); +void test_NullBuf2(void) +{ + char *bp = NULL; + int rc = xsbprintf(&bp, NULL, "blah"); + TEST_ASSERT(rc == -1 && errno == EINVAL); + TEST_ASSERT_EQUAL_PTR(bp, NULL); +} + +extern void test_SmallBuf(void); +void test_SmallBuf(void) +{ + char ba[4]; + char *bp = ba; + char *ep = ba + sizeof(ba); + int rc = xsbprintf(&bp, ep, "1234"); + TEST_ASSERT(rc == 0 && strlen(ba) == 0); + TEST_ASSERT_EQUAL_PTR(bp, ba); +} + +extern void test_MatchBuf(void); +void test_MatchBuf(void) +{ + char ba[5]; + char *bp = ba; + char *ep = ba + sizeof(ba); + int rc = xsbprintf(&bp, ep, "1234"); + TEST_ASSERT(rc == 4 && strlen(ba) == 4); + TEST_ASSERT_EQUAL_PTR(bp, ba + 4); +} + +extern void test_BigBuf(void); +void test_BigBuf(void) +{ + char ba[10]; + char *bp = ba; + char *ep = ba + sizeof(ba); + int rc = xsbprintf(&bp, ep, "1234"); + TEST_ASSERT(rc == 4 && strlen(ba) == 4); + TEST_ASSERT_EQUAL_PTR(bp, ba + 4); +} + +extern void test_SimpleArgs(void); +void test_SimpleArgs(void) +{ + char ba[10]; + char *bp = ba; + char *ep = ba + sizeof(ba); + int rc = xsbprintf(&bp, ep, "%d%d%d%d", 1, 2, 3, 4); + TEST_ASSERT(rc == 4 && strlen(ba) == 4); + TEST_ASSERT_EQUAL_PTR(bp, ba + 4); + TEST_ASSERT_FALSE(strcmp(ba, "1234")); +} +