Preserve argv boundaries and empty arguments passed to main
Build / AerScript (push) Successful in 38s

This commit is contained in:
2026-10-27 19:28:55 +01:00
parent fa32262998
commit d85154ac58
2 changed files with 32 additions and 16 deletions
+31 -16
View File
@@ -1653,6 +1653,7 @@ PH7_PRIVATE sxi32 PH7_VmInit(
/* Virtual machine internal containers */
SyBlobInit(&pVm->sConsumer, &pVm->sAllocator);
SyBlobInit(&pVm->sArgv, &pVm->sAllocator);
SyBlobInit(&pVm->sArgvEntries, &pVm->sAllocator);
SySetInit(&pVm->aLitObj, &pVm->sAllocator, sizeof(ph7_value));
SySetAlloc(&pVm->aLitObj, 0xFF);
SyHashInit(&pVm->hHostFunction, &pVm->sAllocator, 0, 0);
@@ -1963,6 +1964,7 @@ PH7_PRIVATE sxi32 PH7_VmRelease(ph7_vm *pVm) {
/* Free up the heap */
SySetRelease(&pVm->aModules);
SySetRelease(&pVm->aModuleHandles);
SyBlobRelease(&pVm->sArgvEntries);
/* Release the private memory subsystem */
SyMemBackendRelease(&pVm->sAllocator);
return SXRET_OK;
@@ -2454,16 +2456,29 @@ PH7_PRIVATE sxi32 PH7_VmConfigure(
case PH7_VM_CONFIG_ARGV_ENTRY: {
/* Script arguments */
const char *zValue = va_arg(ap, const char *);
sxu32 n;
if(SX_EMPTY_STR(zValue)) {
sxu32 n, nText, nEntries;
if(zValue == 0) {
rc = SXERR_EMPTY;
break;
}
n = (sxu32)SyStrlen(zValue);
if(SyBlobLength(&pVm->sArgv) > 0) {
SyBlobAppend(&pVm->sArgv, (const void *)" ", sizeof(char));
nText = SyBlobLength(&pVm->sArgv);
nEntries = SyBlobLength(&pVm->sArgvEntries);
/* Keep exact entries separately from getopt's legacy flat text. */
rc = SyBlobAppend(&pVm->sArgvEntries, zValue, n + 1);
if(rc == SXRET_OK && n > 0) {
if(nText > 0) {
rc = SyBlobAppend(&pVm->sArgv, (const void *)" ", sizeof(char));
}
if(rc == SXRET_OK) {
rc = SyBlobAppend(&pVm->sArgv, zValue, n);
}
}
if(rc != SXRET_OK) {
/* Neither representation may retain a partially added entry. */
pVm->sArgv.nByte = nText;
pVm->sArgvEntries.nByte = nEntries;
}
SyBlobAppend(&pVm->sArgv, (const void *)zValue, n);
break;
}
case PH7_VM_CONFIG_IO_STREAM: {
@@ -6384,8 +6399,8 @@ PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm) {
ph7_class_method *pMain;
ph7_value *pArgs, *sArgv;
ph7_value pResult;
char *zDup, *zParam;
sxu32 nByte;
const char *zParam;
sxu32 nByte, nOffset;
/* Make sure we are ready to execute this program */
if(pVm->nMagic != PH7_VM_RUN) {
return (pVm->nMagic == PH7_VM_EXEC || pVm->nMagic == PH7_VM_INCL) ? SXERR_LOCKED /* Locked VM */ : SXERR_CORRUPT; /* Stale VM */
@@ -6418,16 +6433,16 @@ PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm) {
if(!pArgs || !sArgv) {
PH7_VmMemoryError(&(*pVm));
}
nByte = SyBlobLength(&pVm->sArgv);
if(nByte > 0) {
zDup = SyMemBackendStrDup(&pVm->sAllocator, SyBlobData(&pVm->sArgv), nByte);
zParam = SyStrtok(zDup, " ");
while(zParam != NULL) {
ph7_value_string(sArgv, zParam, SyStrlen(zParam));
ph7_array_add_elem(pArgs, 0, sArgv);
ph7_value_reset_string_cursor(sArgv);
zParam = SyStrtok(NULL, " ");
MemObjSetType(sArgv, MEMOBJ_STRING);
for(nOffset = 0; nOffset < SyBlobLength(&pVm->sArgvEntries); nOffset += nByte + 1) {
zParam = (const char *)SyBlobDataAt(&pVm->sArgvEntries, nOffset);
nByte = SyStrlen(zParam);
/* Check the actual copy result; ph7_value_string() hides allocation errors. */
if(SyBlobAppend(&sArgv->sBlob, zParam, nByte) != SXRET_OK ||
ph7_array_add_elem(pArgs, 0, sArgv) != PH7_OK) {
PH7_VmMemoryError(&(*pVm));
}
ph7_value_reset_string_cursor(sArgv);
}
pMethod = pMain;
/* A set of arguments is stored in array of strings */
+1
View File
@@ -1221,6 +1221,7 @@ struct ph7_vm {
SyHash hDBAL; /* DBAL installed drivers */
SyBlob sConsumer; /* Default VM consumer [i.e Redirect all VM output to this blob] */
SyBlob sArgv; /* $argv[] collector [refer to the [getopt()] implementation for more information] */
SyBlob sArgvEntries; /* VM-owned argument list, each entry terminated by NUL */
SySet aModules; /* Set of loaded modules */
SySet aModuleHandles; /* Libraries retained after initialization attempts */
SySet aFiles; /* SyString pointers, VM-owned until release */