diff --git a/engine/compiler.c b/engine/compiler.c index 16fc02f..9538e61 100644 --- a/engine/compiler.c +++ b/engine/compiler.c @@ -678,8 +678,10 @@ static sxi32 PH7_GenStateCompileString(ph7_gen_state *pGen) { { const char *zPtr = zIn; sxu32 c = 0; + unsigned char cByte; sxi32 iBase = 8; sxi32 bBraced = FALSE; + sxi32 bOutOfRange = FALSE; sxu32 nDigit = 0; sxu32 nLimit = 3; if(zIn[0] < '0' || zIn[0] > '7') { @@ -706,8 +708,12 @@ static sxi32 PH7_GenStateCompileString(ph7_gen_state *pGen) { } break; } - /* Unsigned accumulation avoids signed overflow on long digit streams. */ - c = c * (sxu32)iBase + (sxu32)iDigit; + /* Keep scanning for syntax errors without overflowing the byte value. */ + if(c > (255 - (sxu32)iDigit) / (sxu32)iBase) { + bOutOfRange = TRUE; + } else if(!bOutOfRange) { + c = c * (sxu32)iBase + (sxu32)iDigit; + } nDigit++; zPtr++; } @@ -722,7 +728,12 @@ static sxi32 PH7_GenStateCompileString(ph7_gen_state *pGen) { } zPtr++; } - PH7_MemObjStringAppend(pObj, (const char *)&c, sizeof(char)); + if(bOutOfRange) { + PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "Numeric escape value exceeds 255"); + return SXERR_ABORT; + } + cByte = (unsigned char)c; + PH7_MemObjStringAppend(pObj, (const char *)&cByte, sizeof(cByte)); n = (sxu32)(zPtr - zIn); } break;