fix memory overflow when doing very large writes on strings (obs from Jos Deroo).
This commit is contained in:
parent
11fb9183e1
commit
9c74080512
31
C/iopreds.c
31
C/iopreds.c
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Reference in New Issue