Reject local shadowing across auxiliary VM frames
Build / AerScript (push) Failing after 36s

This commit is contained in:
2026-10-29 23:06:08 +01:00
parent 3c194e3fa6
commit cbe233a2fa
+27 -9
View File
@@ -55,6 +55,19 @@ struct SyhttpHeader {
#define HTTP_PROTO_11 2 /* HTTP/1.1 */
#define HTTP_PROTO_20 3 /* HTTP/2.0 */
static void VmScopeRecord(ph7_vm *pVm, const SyString *pName, sxi32 bConst);
/* Lookup visible local names across auxiliary frames, never caller invocations.
* Scope exit removes names from these tables without releasing retained storage. */
static SyHashEntry *VmLookupLocal(VmFrame *pFrame, const SyString *pName, sxi32 bConst) {
for(;;) {
SyHashEntry *pEntry = SyHashGet(bConst ? &pFrame->hConst : &pFrame->hVar,
pName->zString, pName->nByte);
if(pEntry || pFrame->pParent == 0 ||
(pFrame->iFlags & (VM_FRAME_LOOP | VM_FRAME_EXCEPTION | VM_FRAME_CATCH | VM_FRAME_FINALLY)) == 0) {
return pEntry;
}
pFrame = pFrame->pParent;
}
}
/*
* Register a constant and it's associated expansion callback so that
* it can be expanded from the target PHP program.
@@ -88,6 +101,9 @@ PH7_PRIVATE sxi32 PH7_VmRegisterConstant(
pFrame = pFrame->pParent;
}
pCollection = &pFrame->hConst;
if(VmLookupLocal(pFrame, pName, TRUE)) {
return SXERR_EXISTS;
}
}
pEntry = SyHashGet(pCollection, (const void *)pName->zString, pName->nByte);
if(pEntry) {
@@ -2262,8 +2278,8 @@ static ph7_value *VmCreateMemObj(
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
pFrame = pFrame->pParent;
}
/* Query the top active frame */
pEntry = SyHashGet(&pFrame->hVar, (const void *)pName->zString, pName->nByte);
/* Auxiliary frames do not permit shadowing a visible local. */
pEntry = VmLookupLocal(pFrame, pName, FALSE);
if(pEntry) {
/* Variable already exists */
return 0;
@@ -3293,7 +3309,7 @@ Resume:
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
pFrame = pFrame->pParent;
}
if(SyHashGet(&pFrame->hVar, pStatic->sName.zString, pStatic->sName.nByte)) {
if(VmLookupLocal(pFrame, &pStatic->sName, FALSE)) {
PH7_VmThrowError(pVm, PH7_CTX_ERR, "Redeclaration of ‘$%z’ variable", &pStatic->sName);
}
if(pStatic->nIdx == SXU32_HIGH) {
@@ -3440,7 +3456,7 @@ Resume:
/* Candidate for expansion via user defined callbacks */
for(;;) {
pEntry = SyHashGet(&pFrame->hConst, SyBlobData(&pObj->sBlob), SyBlobLength(&pObj->sBlob));
if(pEntry == 0 && pFrame->iFlags & VM_FRAME_LOOP && pFrame->pParent) {
if(pEntry == 0 && pFrame->iFlags & (VM_FRAME_LOOP | VM_FRAME_EXCEPTION | VM_FRAME_CATCH | VM_FRAME_FINALLY) && pFrame->pParent) {
pFrame = pFrame->pParent;
} else {
break;
@@ -9335,13 +9351,15 @@ static sxi32 VmExecExceptionBlock(ph7_vm *pVm, ph7_exception *pException,
rc = VmEnterFrame(pVm, 0, 0, &pFrame);
if(rc == SXRET_OK) {
if(pCatch) {
ph7_value *pObj = VmCreateMemObj(pVm, &pCatch->sThis, FALSE);
ph7_value *pObj;
pFrame->iFlags |= VM_FRAME_CATCH;
if(pObj) {
pThis->iRef++;
pObj->x.pOther = pThis;
MemObjSetType(pObj, MEMOBJ_OBJ);
pObj = VmCreateMemObj(pVm, &pCatch->sThis, FALSE);
if(pObj == 0) {
PH7_VmThrowError(pVm, PH7_CTX_ERR, "Redeclaration of ‘$%z’ variable", &pCatch->sThis);
}
pThis->iRef++;
pObj->x.pOther = pThis;
MemObjSetType(pObj, MEMOBJ_OBJ);
} else {
pFrame->iFlags |= VM_FRAME_FINALLY;
}