fix overflow in copy_term's internal stack
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@434 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
parent
0e6dd4734e
commit
83a9b6530e
@ -30,7 +30,7 @@ typedef struct {
|
|||||||
} *vcell;
|
} *vcell;
|
||||||
|
|
||||||
|
|
||||||
STATIC_PROTO(void copy_complex_term, (CELL *, CELL *, CELL *, CELL *));
|
STATIC_PROTO(int copy_complex_term, (CELL *, CELL *, CELL *, CELL *));
|
||||||
STATIC_PROTO(CELL vars_in_complex_term, (CELL *, CELL *));
|
STATIC_PROTO(CELL vars_in_complex_term, (CELL *, CELL *));
|
||||||
STATIC_PROTO(Int p_non_singletons_in_term, (void));
|
STATIC_PROTO(Int p_non_singletons_in_term, (void));
|
||||||
STATIC_PROTO(CELL non_singletons_in_complex_term, (CELL *, CELL *));
|
STATIC_PROTO(CELL non_singletons_in_complex_term, (CELL *, CELL *));
|
||||||
@ -54,7 +54,8 @@ clean_tr(tr_fr_ptr TR0) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *ptf, CELL *HLow)
|
static int
|
||||||
|
copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *ptf, CELL *HLow)
|
||||||
{
|
{
|
||||||
|
|
||||||
CELL **to_visit = (CELL **)(HeapTop + sizeof(CELL));
|
CELL **to_visit = (CELL **)(HeapTop + sizeof(CELL));
|
||||||
@ -82,6 +83,9 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
|
|||||||
*ptf = AbsPair(H);
|
*ptf = AbsPair(H);
|
||||||
ptf++;
|
ptf++;
|
||||||
#ifdef RATIONAL_TREES
|
#ifdef RATIONAL_TREES
|
||||||
|
if (to_visit + 4 >= (CELL **)H0) {
|
||||||
|
goto heap_overflow;
|
||||||
|
}
|
||||||
to_visit[0] = pt0;
|
to_visit[0] = pt0;
|
||||||
to_visit[1] = pt0_end;
|
to_visit[1] = pt0_end;
|
||||||
to_visit[2] = ptf;
|
to_visit[2] = ptf;
|
||||||
@ -91,6 +95,9 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
|
|||||||
to_visit += 4;
|
to_visit += 4;
|
||||||
#else
|
#else
|
||||||
if (pt0 < pt0_end) {
|
if (pt0 < pt0_end) {
|
||||||
|
if (to_visit + 3 >= (CELL **)H0) {
|
||||||
|
goto heap_overflow;
|
||||||
|
}
|
||||||
to_visit[0] = pt0;
|
to_visit[0] = pt0;
|
||||||
to_visit[1] = pt0_end;
|
to_visit[1] = pt0_end;
|
||||||
to_visit[2] = ptf;
|
to_visit[2] = ptf;
|
||||||
@ -126,6 +133,9 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
|
|||||||
ptf++;
|
ptf++;
|
||||||
/* store the terms to visit */
|
/* store the terms to visit */
|
||||||
#ifdef RATIONAL_TREES
|
#ifdef RATIONAL_TREES
|
||||||
|
if (to_visit + 4 >= (CELL **)H0) {
|
||||||
|
goto heap_overflow;
|
||||||
|
}
|
||||||
to_visit[0] = pt0;
|
to_visit[0] = pt0;
|
||||||
to_visit[1] = pt0_end;
|
to_visit[1] = pt0_end;
|
||||||
to_visit[2] = ptf;
|
to_visit[2] = ptf;
|
||||||
@ -135,6 +145,9 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
|
|||||||
to_visit += 4;
|
to_visit += 4;
|
||||||
#else
|
#else
|
||||||
if (pt0 < pt0_end) {
|
if (pt0 < pt0_end) {
|
||||||
|
if (to_visit + 3 >= (CELL **)H0) {
|
||||||
|
goto heap_overflow;
|
||||||
|
}
|
||||||
to_visit[0] = pt0;
|
to_visit[0] = pt0;
|
||||||
to_visit[1] = pt0_end;
|
to_visit[1] = pt0_end;
|
||||||
to_visit[2] = ptf;
|
to_visit[2] = ptf;
|
||||||
@ -231,7 +244,7 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
|
|||||||
/* restore our nice, friendly, term to its original state */
|
/* restore our nice, friendly, term to its original state */
|
||||||
HB = HB0;
|
HB = HB0;
|
||||||
clean_tr(TR0);
|
clean_tr(TR0);
|
||||||
return;
|
return(0);
|
||||||
|
|
||||||
overflow:
|
overflow:
|
||||||
/* oops, we're in trouble */
|
/* oops, we're in trouble */
|
||||||
@ -249,6 +262,25 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
clean_tr(TR0);
|
clean_tr(TR0);
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
heap_overflow:
|
||||||
|
/* oops, we're in trouble */
|
||||||
|
H = HLow;
|
||||||
|
/* we've done it */
|
||||||
|
/* restore our nice, friendly, term to its original state */
|
||||||
|
HB = HB0;
|
||||||
|
#ifdef RATIONAL_TREES
|
||||||
|
while (to_visit > (CELL **)(HeapTop + sizeof(CELL))) {
|
||||||
|
to_visit -= 4;
|
||||||
|
pt0 = to_visit[0];
|
||||||
|
pt0_end = to_visit[1];
|
||||||
|
ptf = to_visit[2];
|
||||||
|
*pt0 = (CELL)to_visit[3];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
clean_tr(TR0);
|
||||||
|
return(-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Term
|
Term
|
||||||
@ -259,16 +291,25 @@ CopyTerm(Term inp) {
|
|||||||
#if COROUTINING
|
#if COROUTINING
|
||||||
if (IsAttachedTerm(t)) {
|
if (IsAttachedTerm(t)) {
|
||||||
CELL *Hi;
|
CELL *Hi;
|
||||||
|
int res;
|
||||||
restart_attached:
|
restart_attached:
|
||||||
|
|
||||||
*H = t;
|
*H = t;
|
||||||
Hi = H+1;
|
Hi = H+1;
|
||||||
H += 2;
|
H += 2;
|
||||||
copy_complex_term(Hi-2, Hi-1, Hi, Hi);
|
if ((res = copy_complex_term(Hi-2, Hi-1, Hi, Hi)) < 0) {
|
||||||
if (H == Hi) { /* handle overflow */
|
if (res == -1) { /* handle overflow */
|
||||||
gc(2, ENV, P);
|
gc(2, ENV, P);
|
||||||
t = Deref(ARG1);
|
t = Deref(ARG1);
|
||||||
goto restart_attached;
|
goto restart_attached;
|
||||||
|
} else { /* handle overflow */
|
||||||
|
if (!growheap(FALSE)) {
|
||||||
|
Error(SYSTEM_ERROR, TermNil, "YAP failed to reserve space in growheap");
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
t = Deref(ARG1);
|
||||||
|
goto restart_attached;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return(Hi[0]);
|
return(Hi[0]);
|
||||||
}
|
}
|
||||||
@ -286,11 +327,22 @@ CopyTerm(Term inp) {
|
|||||||
Hi = H;
|
Hi = H;
|
||||||
tf = AbsPair(H);
|
tf = AbsPair(H);
|
||||||
H += 2;
|
H += 2;
|
||||||
copy_complex_term(ap-1, ap+1, Hi, Hi);
|
{
|
||||||
if (H == Hi) { /* handle overflow */
|
int res;
|
||||||
gc(2, ENV, P);
|
if ((res = copy_complex_term(ap-1, ap+1, Hi, Hi)) < 0) {
|
||||||
t = Deref(ARG1);
|
if (res == -1) { /* handle overflow */
|
||||||
goto restart_list;
|
gc(2, ENV, P);
|
||||||
|
t = Deref(ARG1);
|
||||||
|
goto restart_list;
|
||||||
|
} else { /* handle overflow */
|
||||||
|
if (!growheap(FALSE)) {
|
||||||
|
Error(SYSTEM_ERROR, TermNil, "YAP failed to reserve space in growheap");
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
t = Deref(ARG1);
|
||||||
|
goto restart_list;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return(tf);
|
return(tf);
|
||||||
} else {
|
} else {
|
||||||
@ -306,11 +358,22 @@ CopyTerm(Term inp) {
|
|||||||
tf = AbsAppl(H);
|
tf = AbsAppl(H);
|
||||||
H[0] = (CELL)f;
|
H[0] = (CELL)f;
|
||||||
H += 1+ArityOfFunctor(f);
|
H += 1+ArityOfFunctor(f);
|
||||||
copy_complex_term(ap, ap+ArityOfFunctor(f), HB0+1, HB0);
|
{
|
||||||
if (H == HB0) {
|
int res;
|
||||||
gc(2, ENV, P);
|
if ((res = copy_complex_term(ap, ap+ArityOfFunctor(f), HB0+1, HB0)) < 0) {
|
||||||
t = Deref(ARG1);
|
if (res == -1) {
|
||||||
goto restart_appl;
|
gc(2, ENV, P);
|
||||||
|
t = Deref(ARG1);
|
||||||
|
goto restart_appl;
|
||||||
|
} else { /* handle overflow */
|
||||||
|
if (!growheap(FALSE)) {
|
||||||
|
Error(SYSTEM_ERROR, TermNil, "YAP failed to reserve space in growheap");
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
t = Deref(ARG1);
|
||||||
|
goto restart_appl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return(tf);
|
return(tf);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user