From 15108f2577596235d3f47cef57cd692908910bbe Mon Sep 17 00:00:00 2001 From: Sang Woo Kim Date: Sun, 19 Jul 2026 17:39:06 +0900 Subject: [PATCH 1/4] sCalc: clamp the shift count against a negative operand RIGHT_SHIFT/LEFT_SHIFT clamped the character-shift count above at SCALC_STRING_SIZE but never below. A negative count makes the string branch read/write past the 40-byte local_string: RIGHT_SHIFT reads ps->s[i-j] (j<0) beyond the buffer, and LEFT_SHIFT runs i up to SCALC_STRING_SIZE-j (>40), writing ps->s[i] into the adjacent stack cell. Clamp the count to [0, SCALC_STRING_SIZE] with the same myMAX(myMIN(...)) idiom already used by the SUBRANGE bounds below. --- calcApp/src/sCalcPerform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/calcApp/src/sCalcPerform.c b/calcApp/src/sCalcPerform.c index 31816ac..c7c885e 100644 --- a/calcApp/src/sCalcPerform.c +++ b/calcApp/src/sCalcPerform.c @@ -1265,7 +1265,7 @@ epicsShareFunc long ps1 = ps; toDouble(ps1); j = myNINT(ps1->d); - j = myMIN(j,SCALC_STRING_SIZE); + j = myMAX(myMIN(j,SCALC_STRING_SIZE),0); DEC(ps); if (isDouble(ps)) { /* numeric variable: bit shift by integer amount */ From bdac23f3a24cca6f4ce0f8da23bc1b3f68be41b7 Mon Sep 17 00:00:00 2001 From: Sang Woo Kim Date: Sun, 19 Jul 2026 17:39:15 +0900 Subject: [PATCH 2/4] sCalc: bound the LITERAL_STRING copy by incrementing its counter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LITERAL_STRING copy loop was written as a bounded copy — for (i=0; (is = &(ps->local_string[0]); s = ps->s; - for (i=0; (i Date: Sun, 19 Jul 2026 17:39:24 +0900 Subject: [PATCH 3/4] aCalc: cap the SUBRANGE upper bound at arraySize-1 j is an inclusive array index but was clamped to arraySize, which the element count itself (e.g. AA[3,N]) reaches. The SUBRANGE copy loop for (k=0; i<=j; k++, i++) ps->a[k] = ps->a[i] then reads ps->a[arraySize], one past the arraySize-element buffer. Cap j at arraySize-1 so the inclusive loop stops at the last valid element; this also corrects the SUBRANGE_IP numEl (j+1) which over-reported by one at the boundary. --- calcApp/src/aCalcPerform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/calcApp/src/aCalcPerform.c b/calcApp/src/aCalcPerform.c index 66f5e60..2c05b86 100644 --- a/calcApp/src/aCalcPerform.c +++ b/calcApp/src/aCalcPerform.c @@ -1531,7 +1531,7 @@ long aCalcPerform(double *p_dArg, int num_dArgs, double **pp_aArg, j = (int)ps2->d; if (j < 0) j += arraySize; i = myMAX(myMIN(i,arraySize),0); - j = myMIN(j,arraySize); + j = myMIN(j,arraySize-1); if (aCalcPerformDebug > 20) printf("\tSUBRANGE*: ix1=%d, ix2=%d\n", i, j); if (op == SUBRANGE) { ps->firstEl = 0; From 01e0ea550935abf5ebf826a7cabd987fd96098c8 Mon Sep 17 00:00:00 2001 From: Sang Woo Kim Date: Sun, 19 Jul 2026 17:39:35 +0900 Subject: [PATCH 4/4] calcUtil: reject an nderiv fit window larger than the array nderiv() fixes the fit window at m = 2*npts+1 (5 for deriv()) and called fitpoly(x,y,m,...) plus the tail loop lx[j]=x[(n-m)+j] regardless of the caller's point count n. With n