diff options
author | Andrew J. Schorr <aschorr@telemetry-investments.com> | 2017-11-14 14:28:48 -0500 |
---|---|---|
committer | Andrew J. Schorr <aschorr@telemetry-investments.com> | 2017-11-14 14:28:48 -0500 |
commit | 064d78b562c9670751c48673c6d1d171aff51a42 (patch) | |
tree | 8c50b4d4a4ba82be1a482ab3927dab6ded648fc7 /field.c | |
parent | fe60f215f0dc446e39d69d4663cbb8c5ef406535 (diff) | |
download | egawk-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.c | 16 |
1 files changed, 11 insertions, 5 deletions
@@ -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; |