diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2014-11-11 23:12:01 +0200 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2014-11-11 23:12:01 +0200 |
commit | b4cf3cc470eb1200ec90fcc7ad5b2d069059cf7e (patch) | |
tree | 018a69e2dfd74b91f01bf452d4708f10ce2f3c52 | |
parent | 350265fafb2a0153d4207c67d626f135b308ad34 (diff) | |
download | egawk-b4cf3cc470eb1200ec90fcc7ad5b2d069059cf7e.tar.gz egawk-b4cf3cc470eb1200ec90fcc7ad5b2d069059cf7e.tar.bz2 egawk-b4cf3cc470eb1200ec90fcc7ad5b2d069059cf7e.zip |
Fix memory growth problem.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | field.c | 6 | ||||
-rw-r--r-- | interpret.h | 24 |
3 files changed, 36 insertions, 4 deletions
@@ -1,3 +1,13 @@ +2014-11-11 Arnold D. Robbins <arnold@skeeve.com> + + Don't let memory used increase linearly in the size of + the input. Problem reported by dragan legic + <dragan.legic@yandex.ru>. + + * field.c (set_record): NUL-terminate the buffer. + * interpret.h (r_interpret): Op_field_spec: if it's $0, increment + the valref. Op_store_var: if we got $0, handle it appropriately. + 2014-11-10 Arnold D. Robbins <arnold@skeeve.com> Reorder main.c activities so that we can set a locale on the @@ -277,6 +277,12 @@ set_record(const char *buf, int cnt) /* copy the data */ memcpy(databuf, buf, cnt); + /* + * Add terminating '\0' so that C library routines + * will know when to stop. + */ + databuf[cnt] = '\0'; + /* manage field 0: */ unref(fields_arr[0]); getnode(n); diff --git a/interpret.h b/interpret.h index 28804330..593f11a6 100644 --- a/interpret.h +++ b/interpret.h @@ -340,7 +340,12 @@ uninitialized_scalar: lhs = r_get_field(t1, (Func_ptr *) 0, true); decr_sp(); DEREF(t1); - r = dupnode(*lhs); /* can't use UPREF here */ + /* only for $0, up ref count */ + if (*lhs == fields_arr[0]) { + r = *lhs; + UPREF(r); + } else + r = dupnode(*lhs); PUSH(r); break; @@ -649,11 +654,22 @@ mod: lhs = get_lhs(pc->memory, false); unref(*lhs); r = pc->initval; /* constant initializer */ - if (r == NULL) - *lhs = POP_SCALAR(); - else { + if (r != NULL) { UPREF(r); *lhs = r; + } else { + r = POP_SCALAR(); + + /* if was a field, turn it into a var */ + if ((r->flags & FIELD) == 0) { + *lhs = r; + } else if (r->valref == 1) { + r->flags &= ~FIELD; + *lhs = r; + } else { + *lhs = dupnode(r); + DEREF(r); + } } break; |