fix memory overflow when doing very large writes on strings (obs from Jos Deroo).

This commit is contained in:
Vitor Santos Costa 2009-07-28 18:30:15 -05:00
parent 11fb9183e1
commit 9c74080512
3 changed files with 30 additions and 9 deletions

View File

@ -742,13 +742,21 @@ MemPutc(int sno, int ch)
}
#endif
s->u.mem_string.buf[s->u.mem_string.pos++] = ch;
if (s->u.mem_string.pos == s->u.mem_string.max_size) {
if (s->u.mem_string.pos >= s->u.mem_string.max_size -256) {
extern int Yap_page_size;
int old_src = s->u.mem_string.src, new_src;
/* oops, we have reached an overflow */
Int new_max_size = s->u.mem_string.max_size + Yap_page_size;
char *newbuf;
if ((newbuf = Yap_AllocAtomSpace(new_max_size*sizeof(char))) == NULL) {
if ((newbuf = Yap_AllocAtomSpace(new_max_size*sizeof(char))) != NULL) {
new_src = MEM_BUF_CODE;
#if !USE_SYSTEM_MALLOC
} else if ((newbuf = (ADDR)malloc(new_max_size*sizeof(char))) != NULL) {
new_src = MEM_BUF_MALLOC;
#endif
} else {
if (Stream[sno].u.mem_string.error_handler) {
Yap_Error_Size = new_max_size*sizeof(char);
save_machine_regs();
@ -770,9 +778,14 @@ MemPutc(int sno, int ch)
}
}
#endif
Yap_FreeAtomSpace(s->u.mem_string.buf);
if (old_src == MEM_BUF_CODE) {
Yap_FreeAtomSpace(s->u.mem_string.buf);
} else {
free(s->u.mem_string.buf);
}
s->u.mem_string.buf = newbuf;
s->u.mem_string.max_size = new_max_size;
s->u.mem_string.src = new_src;
}
count_output_char(ch,s);
return ((int) ch);
@ -2740,6 +2753,7 @@ open_buf_read_stream(char *nbuf, Int nchars)
st->u.mem_string.buf = nbuf;
st->u.mem_string.max_size = nchars;
st->u.mem_string.error_handler = NULL;
st->u.mem_string.src = MEM_BUF_CODE;
return sno;
}
@ -3235,7 +3249,11 @@ Yap_CloseStreams (int loud)
}
#endif
else if (Stream[sno].status & InMemory_Stream_f) {
Yap_FreeAtomSpace(Stream[sno].u.mem_string.buf);
if (Stream[sno].u.mem_string.src == MEM_BUF_CODE) {
Yap_FreeAtomSpace(Stream[sno].u.mem_string.buf);
} else {
free(Stream[sno].u.mem_string.buf);
}
} else if (!(Stream[sno].status & Null_Stream_f))
YP_fclose (Stream[sno].u.file.file);
else {
@ -3272,7 +3290,10 @@ CloseStream(int sno)
#endif
}
else if (Stream[sno].status & (InMemory_Stream_f)) {
Yap_FreeAtomSpace(Stream[sno].u.mem_string.buf);
if (Stream[sno].u.mem_string.src == MEM_BUF_CODE)
Yap_FreeAtomSpace(Stream[sno].u.mem_string.buf);
else
free(Stream[sno].u.mem_string.buf);
}
Stream[sno].status = Free_Stream_f;
PurgeAlias(sno);

View File

@ -172,10 +172,6 @@ low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args)
LOCK(Yap_heap_regs->low_level_trace_lock);
sc = Yap_heap_regs;
vsc_count++;
if (vsc_count < 50000)
return;
if (vsc_count == 50084)
jmp_deb(1);
#ifdef THREADS
Yap_heap_regs->thread_handle[worker_id].thread_inst_count++;
#endif

View File

@ -40,6 +40,9 @@ FILE *rl_instream, *rl_outstream;
#endif
#define MEM_BUF_CODE 0
#define MEM_BUF_MALLOC 1
typedef int (*GetsFunc)(int, UInt, char *);
typedef struct stream_desc
@ -57,6 +60,7 @@ typedef struct stream_desc
} file;
struct {
char *buf; /* where the file is being read from/written to */
int src; /* where the space comes from, 0 code space, 1 malloc */
Int max_size; /* maximum buffer size (may be changed dynamically) */
UInt pos;
volatile void *error_handler;