aboutsummaryrefslogtreecommitdiffstats
path: root/field.c
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2017-11-14 14:28:48 -0500
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2017-11-14 14:28:48 -0500
commit064d78b562c9670751c48673c6d1d171aff51a42 (patch)
tree8c50b4d4a4ba82be1a482ab3927dab6ded648fc7 /field.c
parentfe60f215f0dc446e39d69d4663cbb8c5ef406535 (diff)
downloadegawk-064d78b562c9670751c48673c6d1d171aff51a42.tar.gz
egawk-064d78b562c9670751c48673c6d1d171aff51a42.tar.bz2
egawk-064d78b562c9670751c48673c6d1d171aff51a42.zip
Fix field corruption when $0 is reassigned with open $n references.
Diffstat (limited to 'field.c')
-rw-r--r--field.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/field.c b/field.c
index 5ab718d4..5263cc61 100644
--- a/field.c
+++ b/field.c
@@ -341,14 +341,20 @@ static void
purge_record()
{
int i;
- NODE *n;
NF = -1;
for (i = 1; i <= parse_high_water; i++) {
- assert((fields_arr[i]->flags & MALLOC) == 0
- ? fields_arr[i]->valref == 1
- : true);
- unref(fields_arr[i]);
+ NODE *n;
+ NODE *r = fields_arr[i];
+ if ((r->flags & MALLOC) == 0 && r->valref > 1) {
+ /* This can and does happen. We must copy the string! */
+ const char *save = r->stptr;
+ emalloc(r->stptr, char *, r->stlen + 1, "purge_record");
+ memcpy(r->stptr, save, r->stlen);
+ r->stptr[r->stlen] = '\0';
+ r->flags |= MALLOC;
+ }
+ unref(r);
getnode(n);
*n = *Null_field;
fields_arr[i] = n;