From 8382367495a3960a035677af21b595dd64b94319 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 21 Apr 2017 14:53:23 -0400 Subject: [PATCH 1/3] libCom/test: epicsCalcTest use exact postifx buffers exposes INFIX_TO_POSTFIX_SIZE() bug --- src/libCom/test/epicsCalcTest.cpp | 62 +++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/src/libCom/test/epicsCalcTest.cpp b/src/libCom/test/epicsCalcTest.cpp index f4d5a4660..9bad2000c 100644 --- a/src/libCom/test/epicsCalcTest.cpp +++ b/src/libCom/test/epicsCalcTest.cpp @@ -6,6 +6,9 @@ \*************************************************************************/ // Author: Andrew Johnson +#include +#include + #include "epicsUnitTest.h" #include "epicsTypes.h" #include "epicsMath.h" @@ -20,17 +23,23 @@ double doCalc(const char *expr) { double args[CALCPERFORM_NARGS] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 }; - char rpn[MAX_POSTFIX_SIZE]; + char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); short err; double result = 0.0; result /= result; /* Start as NaN */ - + + if(!rpn) { + testAbort("postfix: %s no memory", expr); + return epicsNAN; + } + if (postfix(expr, rpn, &err)) { testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr); } else if (calcPerform(args, &result, rpn) && finite(result)) { testDiag("calcPerform: error evaluating '%s'", expr); } + free(rpn); return result; } @@ -40,11 +49,16 @@ void testCalc(const char *expr, double expected) { double args[CALCPERFORM_NARGS] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 }; - char rpn[MAX_POSTFIX_SIZE]; + char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); short err; double result = 0.0; result /= result; /* Start as NaN */ + if(!rpn) { + testFail("postfix: %s no memory", expr); + return; + } + if (postfix(expr, rpn, &err)) { testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr); } else @@ -63,6 +77,7 @@ void testCalc(const char *expr, double expected) { testDiag("Expected result is %g, actually got %g", expected, result); calcExprDump(rpn); } + free(rpn); } void testUInt32Calc(const char *expr, epicsUInt32 expected) { @@ -71,12 +86,17 @@ void testUInt32Calc(const char *expr, epicsUInt32 expected) { double args[CALCPERFORM_NARGS] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 }; - char rpn[MAX_POSTFIX_SIZE]; + char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); short err; epicsUInt32 uresult; double result = 0.0; result /= result; /* Start as NaN */ + if(!rpn) { + testFail("postfix: %s no memory", expr); + return; + } + if (postfix(expr, rpn, &err)) { testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr); } else @@ -91,38 +111,50 @@ void testUInt32Calc(const char *expr, epicsUInt32 expected) { expected, expected, uresult, uresult); calcExprDump(rpn); } + free(rpn); } void testArgs(const char *expr, unsigned long einp, unsigned long eout) { - char rpn[MAX_POSTFIX_SIZE]; + char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); short err = 0; unsigned long vinp, vout; + if(!rpn) { + testFail("postfix: %s no memory", expr); + return; + } + if (postfix(expr, rpn, &err)) { - testFail("postfix: %s in expression '%s'", calcErrorStr(err), expr); - return; + testFail("postfix: %s in expression '%s'", calcErrorStr(err), expr); + return; } if (calcArgUsage(rpn, &vinp, &vout)) { - testFail("calcArgUsage returned error for '%s'", expr); - return; + testFail("calcArgUsage returned error for '%s'", expr); + return; } if (!testOk(vinp == einp && vout == eout, "Args for '%s'", expr)) { - testDiag("Expected (%lx, %lx) got (%lx, %lx)", einp, eout, vinp, vout); + testDiag("Expected (%lx, %lx) got (%lx, %lx)", einp, eout, vinp, vout); } + free(rpn); } void testBadExpr(const char *expr, short expected_err) { /* Parse an invalid expression, test against expected error code */ - char rpn[MAX_POSTFIX_SIZE]; + char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); short err = 0; + if(!rpn) { + testFail("postfix: %s no memory", expr); + return; + } + postfix(expr, rpn, &err); if (!testOk(err == expected_err, "Bad expression '%s'", expr)) { - testDiag("Expected '%s', actually got '%s'", - calcErrorStr(expected_err), calcErrorStr(err)); - calcExprDump(rpn); + testDiag("Expected '%s', actually got '%s'", + calcErrorStr(expected_err), calcErrorStr(err)); + calcExprDump(rpn); } - return; + free(rpn); } /* Test an expression that is also valid C code */ From e25a2964bcf57c5ad951e48e99da4bfa327f66f3 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 21 Apr 2017 16:09:36 -0500 Subject: [PATCH 2/3] Fix postfix.h macro arg, document --- src/libCom/calc/postfix.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libCom/calc/postfix.h b/src/libCom/calc/postfix.h index a7a2a3cbe..b90492012 100644 --- a/src/libCom/calc/postfix.h +++ b/src/libCom/calc/postfix.h @@ -19,9 +19,10 @@ #define CALCPERFORM_NARGS 12 #define CALCPERFORM_STACK 80 -#define INFIX_TO_POSTFIX_SIZE(n) (n*21/6) +#define INFIX_TO_POSTFIX_SIZE(n) ((n)*21/6) /* The above expression is an estimate of the maximum postfix buffer - * size needed for a given infix expression buffer. The actual size + * size needed for a given infix expression buffer (the argument must count + * the trailing nil byte in the input expression string). The actual size * needed is never larger than this value, although it is actually a * few bytes smaller for some sizes. * From c5decfbd12cfb239681568edbd1dc9402582a6be Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 24 Apr 2017 18:03:53 -0500 Subject: [PATCH 3/3] Fix for dbCa warning seg-fault Don't queue an errlog message containing a pointer to a string that will disappear soon. Thanks to Matt Pearson for the bug analysis. --- src/db/dbCa.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/db/dbCa.c b/src/db/dbCa.c index 13118eb8b..aaaaa4b5c 100644 --- a/src/db/dbCa.c +++ b/src/db/dbCa.c @@ -142,7 +142,6 @@ static void addAction(caLink *pca, short link_action) if (++removesOutstanding >= removesOutstandingWarning) { errlogPrintf("dbCa::addAction pausing, %d channels to clear\n", removesOutstanding); - printLinks(pca); } while (removesOutstanding >= removesOutstandingWarning) { epicsMutexUnlock(workListLock);