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_11 2 /* HTTP/1.1 */
#define HTTP_PROTO_20 3 /* HTTP/2.0 */ #define HTTP_PROTO_20 3 /* HTTP/2.0 */
static void VmScopeRecord(ph7_vm *pVm, const SyString *pName, sxi32 bConst); 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 * Register a constant and it's associated expansion callback so that
* it can be expanded from the target PHP program. * it can be expanded from the target PHP program.
@@ -88,6 +101,9 @@ PH7_PRIVATE sxi32 PH7_VmRegisterConstant(
pFrame = pFrame->pParent; pFrame = pFrame->pParent;
} }
pCollection = &pFrame->hConst; pCollection = &pFrame->hConst;
if(VmLookupLocal(pFrame, pName, TRUE)) {
return SXERR_EXISTS;
}
} }
pEntry = SyHashGet(pCollection, (const void *)pName->zString, pName->nByte); pEntry = SyHashGet(pCollection, (const void *)pName->zString, pName->nByte);
if(pEntry) { if(pEntry) {
@@ -2262,8 +2278,8 @@ static ph7_value *VmCreateMemObj(
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) { while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
pFrame = pFrame->pParent; pFrame = pFrame->pParent;
} }
/* Query the top active frame */ /* Auxiliary frames do not permit shadowing a visible local. */
pEntry = SyHashGet(&pFrame->hVar, (const void *)pName->zString, pName->nByte); pEntry = VmLookupLocal(pFrame, pName, FALSE);
if(pEntry) { if(pEntry) {
/* Variable already exists */ /* Variable already exists */
return 0; return 0;
@@ -3293,7 +3309,7 @@ Resume:
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) { while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
pFrame = pFrame->pParent; 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); PH7_VmThrowError(pVm, PH7_CTX_ERR, "Redeclaration of ‘$%z’ variable", &pStatic->sName);
} }
if(pStatic->nIdx == SXU32_HIGH) { if(pStatic->nIdx == SXU32_HIGH) {
@@ -3440,7 +3456,7 @@ Resume:
/* Candidate for expansion via user defined callbacks */ /* Candidate for expansion via user defined callbacks */
for(;;) { for(;;) {
pEntry = SyHashGet(&pFrame->hConst, SyBlobData(&pObj->sBlob), SyBlobLength(&pObj->sBlob)); 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; pFrame = pFrame->pParent;
} else { } else {
break; break;
@@ -9335,13 +9351,15 @@ static sxi32 VmExecExceptionBlock(ph7_vm *pVm, ph7_exception *pException,
rc = VmEnterFrame(pVm, 0, 0, &pFrame); rc = VmEnterFrame(pVm, 0, 0, &pFrame);
if(rc == SXRET_OK) { if(rc == SXRET_OK) {
if(pCatch) { if(pCatch) {
ph7_value *pObj = VmCreateMemObj(pVm, &pCatch->sThis, FALSE); ph7_value *pObj;
pFrame->iFlags |= VM_FRAME_CATCH; pFrame->iFlags |= VM_FRAME_CATCH;
if(pObj) { pObj = VmCreateMemObj(pVm, &pCatch->sThis, FALSE);
pThis->iRef++; if(pObj == 0) {
pObj->x.pOther = pThis; PH7_VmThrowError(pVm, PH7_CTX_ERR, "Redeclaration of ‘$%z’ variable", &pCatch->sThis);
MemObjSetType(pObj, MEMOBJ_OBJ);
} }
pThis->iRef++;
pObj->x.pOther = pThis;
MemObjSetType(pObj, MEMOBJ_OBJ);
} else { } else {
pFrame->iFlags |= VM_FRAME_FINALLY; pFrame->iFlags |= VM_FRAME_FINALLY;
} }