Упростил патч, выкинул нерелевантный код. Теперь совсем как в букваре по программированию. На следующей неделе приведу исправление (надеюсь, вероятный противник не успеет отформатировать мне систему).
/**
* Run a dependency set loop against rpmdb triggers.
* @param psm package state machine data
* @param tagno dependency set to run against rpmdb
* @param arg2 scriptlet arg2
* @return RPMRC_OK on success
*/
static rpmRC runScriptTriggersLoop(rpmpsm psm, rpmTag tagno, int arg2)
/*@globals rpmGlobalMacroContext, h_errno,
fileSystem, internalState @*/
/*@modifies psm, rpmGlobalMacroContext,
fileSystem, internalState @*/
{
static int scareMem = 0;
const rpmts ts = psm->ts;
rpmfi fi = NULL;
rpmds sourceDs = memset(alloca(sizeof(*sourceDs)), 0, sizeof(*sourceDs));
char * depName = NULL;
char * evr;
char * ptr = NULL;
ARGI_t instances = NULL;
rpmmi mi;
Header triggeredH;
rpmRC rc = RPMRC_OK;
int xx;
rpmtsi pi;
rpmte p = NULL;
int n;
if (tagno == RPMTAG_BASENAMES || tagno == RPMTAG_DIRNAMES)
n = (psm->goal == PSM_PKGINSTALL) ? ts->numAddedFiles : ts->numErasedFiles;
else
n = ts->orderCount;
evr = memset(alloca(n * 64 * sizeof(*evr)), 0, n * 64 * sizeof(*evr));
ptr = evr;
sourceDs->tagN = tagno;
sourceDs->Type = tagName(tagno);
sourceDs->Count = n;
sourceDs->i = -1;
sourceDs->N = memset(alloca(n * sizeof(*sourceDs->N)), 0, n * sizeof(*sourceDs->N));
sourceDs->EVR = memset(alloca(n * sizeof(*sourceDs->EVR)), 0, n * sizeof(*sourceDs->EVR));
sourceDs->Flags = (evrFlags *) memset(alloca(n * sizeof(*sourceDs->Flags)), 0, n * sizeof(*sourceDs->Flags));
pi = rpmtsiInit(ts);
while ((p = rpmtsiNext(pi, psm->goal == PSM_PKGINSTALL ? TR_ADDED : TR_REMOVED)) != NULL) {
if (p->isSource) continue;
if ((fi = rpmtsiFi(pi)) == NULL)
continue;
if (tagno == RPMTAG_BASENAMES || tagno == RPMTAG_DIRNAMES) {
fi = rpmfiInit(fi, 0);
if (fi != NULL) {
while (rpmfiNext(fi) >= 0) {
sourceDs->N[++sourceDs->i] = (tagno == RPMTAG_DIRNAMES ? rpmfiDN(fi) : rpmfiFN(fi));
}
}
} else {
char *ptr = evr;
if (rpmteE(p)) ptr = stpcpy(stpcpy(ptr, rpmteE(p)), ":");
ptr = stpcpy(stpcpy(stpcpy(ptr, rpmteV(p)), "-"), rpmteR(p));
if (rpmteD(p)) ptr = stpcpy(stpcpy(ptr, ":"), rpmteD(p));
sourceDs->N[++sourceDs->i] = rpmteN(p);
sourceDs->EVR[sourceDs->i] = evr++;
sourceDs->Flags[sourceDs->i] = RPMSENSE_EQUAL;
}
}
xx = rpmteClose(p, ts, 0);
pi = rpmtsiFree(pi);
if (sourceDs->i == -1)
return rc;
/* Fire elements against rpmdb trigger strings. */
for(sourceDs->i = 0; sourceDs->i < (int)sourceDs->Count; sourceDs->i++) {
const char * depName = sourceDs->N[sourceDs->i];
unsigned prev, instance;
unsigned nvals;
ARGint_t vals;
if (!depName || !*depName)
return rc;
if (_psm_debug)
rpmlog(RPMLOG_DEBUG, "--> %s:%d depName: %s tagno: %d ix: %d\n", __FUNCTION__, __LINE__, depName, tagno, sourceDs->i);
if (depName[0] == '/' && psm->Tmires != NULL) {
miRE mire;
int j;
/* XXX mireApply doesn't tell which pattern matched. */
for (j = 0, mire = psm->Tmires; j < psm->nTmires; j++, mire++) {
const char * pattern = psm->Tpats[j];
size_t npattern = strlen(pattern);
if (tagno == RPMTAG_DIRNAMES && !PATT_ISDIR(pattern, npattern))
continue;
if (mireRegexec(mire, depName, 0) < 0)
/*@innercontinue@*/ continue;
/* Reset the primary retrieval key to the pattern. */
depName = pattern;
/*@innerbreak@*/ break;
}
}
/* Retrieve triggered header(s) by key. */
mi = rpmtsInitIterator(ts, RPMTAG_TRIGGERNAME, depName, 0);
nvals = argiCount(instances);
vals = argiData(instances);
if (nvals > 0)
xx = rpmmiPrune(mi, (uint32_t *)vals, nvals, 1);
prev = 0;
while((triggeredH = rpmmiNext(mi)) != NULL) {
instance = rpmmiInstance(mi);
if (prev == instance)
/*@innercontinue@*/ continue;
rc |= handleOneScriptTrigger(psm, sourceDs, triggeredH, arg2);
prev = instance;
xx = argiAdd(&instances, -1, instance);
xx = argiSort(instances, NULL);
}
mi = rpmmiFree(mi);
}
instances = argiFree(instances);
return rc;
}
Если к тому времени никто не укажет на ошибку в коде - очевидное переполнение стека - значит обсуждать вопросы безопасности на данном форуме не с кем (компетентные люди слишком редко сюда заглядывают, шибко заняты и т.п.). Аргументы "ахинея", "бред", "дебил" читать было бы очень весело, если бы было от кого.